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.
- checksums.yaml +5 -5
- data/.github/ISSUE_TEMPLATE/bug_report.md +33 -0
- data/.github/ISSUE_TEMPLATE/code_change.md +11 -0
- data/.github/PULL_REQUEST_TEMPLATE.md +25 -0
- data/.github/dependabot.yml +7 -0
- data/.github/workflows/ruby.yml +28 -0
- data/.gitignore +3 -0
- data/.rubocop.yml +41 -0
- data/.ruby-version +1 -0
- data/.tool-versions +1 -0
- data/CHANGELOG.md +131 -0
- data/CODE_OF_CONDUCT.md +8 -0
- data/CONTRIBUTING.md +16 -0
- data/Gemfile +2 -0
- data/IDEAS.md +57 -0
- data/LICENSE.txt +1 -1
- data/README.md +28 -17
- data/Rakefile +14 -8
- data/bin/hoboken +2 -1
- data/hoboken.gemspec +63 -16
- data/lib/hoboken/actions.rb +11 -6
- data/lib/hoboken/add_ons/active_record.rb +142 -0
- data/lib/hoboken/add_ons/airbrake.rb +64 -0
- data/lib/hoboken/add_ons/github_action.rb +14 -0
- data/lib/hoboken/add_ons/heroku.rb +29 -0
- data/lib/hoboken/add_ons/internationalization.rb +28 -0
- data/lib/hoboken/add_ons/metrics.rb +60 -0
- data/lib/hoboken/add_ons/omniauth.rb +174 -0
- data/lib/hoboken/add_ons/rubocop.rb +46 -0
- data/lib/hoboken/add_ons/sequel.rb +135 -0
- data/lib/hoboken/add_ons/sidekiq.rb +137 -0
- data/lib/hoboken/add_ons/travis.rb +15 -0
- data/lib/hoboken/add_ons/turnip.rb +109 -0
- data/lib/hoboken/add_ons/twbs.rb +50 -0
- data/lib/hoboken/add_ons/vcr.rb +54 -0
- data/lib/hoboken/generate.rb +146 -46
- data/lib/hoboken/templates/Gemfile.erb.tt +43 -8
- data/lib/hoboken/templates/README.md.tt +117 -35
- data/lib/hoboken/templates/Rakefile.tt +20 -16
- data/lib/hoboken/templates/active_record.rake +11 -0
- data/lib/hoboken/templates/airbrake.rb.tt +13 -0
- data/lib/hoboken/templates/classic.rb.tt +25 -11
- data/lib/hoboken/templates/classic_environment.rb.tt +51 -0
- data/lib/hoboken/templates/config.ru.tt +4 -2
- data/lib/hoboken/templates/console +19 -0
- data/lib/hoboken/templates/db.rb.tt +24 -0
- data/lib/hoboken/templates/example_worker.rb.tt +14 -0
- data/lib/hoboken/templates/github_action.tt +28 -0
- data/lib/hoboken/templates/gitignore +8 -0
- data/lib/hoboken/templates/metrics.rake.tt +12 -9
- data/lib/hoboken/templates/modular.rb.tt +28 -15
- data/lib/hoboken/templates/modular_environment.rb.tt +62 -0
- data/lib/hoboken/templates/puma.rb.tt +21 -0
- data/lib/hoboken/templates/rspec.rake.tt +9 -0
- data/lib/hoboken/templates/rubocop.yml.tt +51 -0
- data/lib/hoboken/templates/seeds.rb +12 -0
- data/lib/hoboken/templates/sequel.rake +21 -0
- data/lib/hoboken/templates/server +15 -0
- data/lib/hoboken/templates/setup +28 -0
- data/lib/hoboken/templates/sidekiq.rb.tt +21 -0
- data/lib/hoboken/templates/spec/app_spec.rb.tt +13 -0
- data/lib/hoboken/templates/spec/example_worker_spec.rb.tt +16 -0
- data/lib/hoboken/templates/spec/rack_matchers.rb.tt +58 -0
- data/lib/hoboken/templates/spec/spec_helper.rb.tt +37 -0
- data/lib/hoboken/templates/spec/turnip_helper.rb.tt +10 -0
- data/lib/hoboken/templates/styles.css.tt +1 -1
- data/lib/hoboken/templates/support/rack_helpers.rb.tt +55 -0
- data/lib/hoboken/templates/support/rack_test_assertions.rb.tt +113 -0
- data/lib/hoboken/templates/test/test_helper.rb.tt +47 -0
- data/lib/hoboken/templates/test/unit/app_test.rb.tt +11 -3
- data/lib/hoboken/templates/test/unit/example_worker_test.rb.tt +20 -0
- data/lib/hoboken/templates/test_unit.rake.tt +18 -0
- data/lib/hoboken/templates/vcr_setup.rb.tt +15 -0
- data/lib/hoboken/templates/views/index.erb.tt +11 -4
- data/lib/hoboken/templates/views/layout.erb.tt +7 -4
- data/lib/hoboken/version.rb +3 -1
- data/lib/hoboken.rb +147 -325
- data/test/fixtures/Gemfile +3 -3
- data/test/fixtures/Gemfile.pristine +3 -2
- data/test/integration/active_record_test.rb +66 -0
- data/test/integration/airbrake_test.rb +31 -0
- data/test/integration/generate_classic_test.rb +75 -0
- data/test/integration/generate_modular_test.rb +83 -0
- data/test/integration/github_action_test.rb +13 -0
- data/test/integration/heroku_test.rb +14 -0
- data/test/integration/internationalization_test.rb +26 -0
- data/test/integration/metrics_test.rb +54 -0
- data/test/integration/omniauth_test.rb +143 -0
- data/test/integration/rubocop_test.rb +39 -0
- data/test/integration/sequel_test.rb +64 -0
- data/test/integration/sidekiq_test.rb +105 -0
- data/test/integration/travis_test.rb +13 -0
- data/test/integration/turnip_test.rb +51 -0
- data/test/integration/twitter_bootstrap_test.rb +39 -0
- data/test/integration/vcr_test.rb +54 -0
- data/test/test_helper.rb +109 -0
- data/test/unit/hoboken_actions_test.rb +82 -53
- data/www/Gemfile +4 -0
- data/www/README.md +2 -0
- data/www/config.rb +11 -0
- data/www/source/documentation.html.erb +274 -0
- data/www/source/images/hoboken-running.png +0 -0
- data/www/source/images/hoboken.png +0 -0
- data/www/source/images/sinatra.png +0 -0
- data/www/source/index.html.erb +44 -0
- data/www/source/javascripts/all.js +1 -0
- data/www/source/layouts/layout.erb +38 -0
- data/www/source/stylesheets/all.css.scss +116 -0
- data/www/source/stylesheets/normalize.css +375 -0
- metadata +655 -29
- data/lib/hoboken/templates/sprockets.rake +0 -33
- data/lib/hoboken/templates/sprockets_chain.rb +0 -26
- data/lib/hoboken/templates/sprockets_helper.rb +0 -13
- data/lib/hoboken/templates/test/support/rack_test_assertions.rb.tt +0 -79
- 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
|