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,137 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Hoboken
|
4
|
+
module AddOns
|
5
|
+
# Background processing via the Sidekiq gem.
|
6
|
+
#
|
7
|
+
class Sidekiq < ::Hoboken::Group
|
8
|
+
def add_gems
|
9
|
+
gem 'sidekiq', version: '6.2'
|
10
|
+
end
|
11
|
+
|
12
|
+
def adjust_rackup_config
|
13
|
+
gsub_file('config.ru', /run .*::App.*\n/) do |match|
|
14
|
+
<<~CODE
|
15
|
+
require 'sidekiq/web'
|
16
|
+
|
17
|
+
if 'production' == ENV.fetch('RACK_ENV', 'production')
|
18
|
+
Sidekiq::Web.use Rack::Auth::Basic do |username, password|
|
19
|
+
[username, password] == [ENV['SIDEKIQ_USERNAME'], ENV['SIDEKIQ_PASSWORD']]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
Sidekiq::Web.use Rack::Session::Cookie, secret: ENV['SESSION_SECRET']
|
24
|
+
run Rack::URLMap.new('/' => #{match[4...-1].chomp}, '/sidekiq' => Sidekiq::Web)
|
25
|
+
CODE
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def setup_config
|
30
|
+
template('hoboken/templates/sidekiq.rb.tt', 'config/sidekiq.rb')
|
31
|
+
location = "require_relative '../app'"
|
32
|
+
insert_into_file('config/environment.rb', before: location) do
|
33
|
+
"require_relative 'sidekiq'\n\n"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def example_worker
|
38
|
+
empty_directory('workers')
|
39
|
+
template('hoboken/templates/example_worker.rb.tt', 'workers/example_worker.rb')
|
40
|
+
end
|
41
|
+
|
42
|
+
def worker_test_and_helper
|
43
|
+
return if rspec?
|
44
|
+
|
45
|
+
insert_into_file('test/test_helper.rb', after: "require 'rack/test'") do
|
46
|
+
"\nrequire 'sidekiq/testing'"
|
47
|
+
end
|
48
|
+
|
49
|
+
template(
|
50
|
+
'hoboken/templates/test/unit/example_worker_test.rb.tt',
|
51
|
+
'test/unit/example_worker_test.rb'
|
52
|
+
)
|
53
|
+
end
|
54
|
+
|
55
|
+
# rubocop:disable Metrics/MethodLength
|
56
|
+
def worker_spec_and_helper
|
57
|
+
return unless rspec?
|
58
|
+
|
59
|
+
insert_into_file('spec/spec_helper.rb', after: "require 'rack/test'") do
|
60
|
+
"\nrequire 'sidekiq/testing'"
|
61
|
+
end
|
62
|
+
|
63
|
+
snippet = <<~CODE
|
64
|
+
config.before(:each, sidekiq: true) do
|
65
|
+
Sidekiq::Worker.clear_all
|
66
|
+
end
|
67
|
+
CODE
|
68
|
+
|
69
|
+
location = /RSpec\.configure do \|config\|\n/
|
70
|
+
insert_into_file('spec/spec_helper.rb', after: location) do
|
71
|
+
"#{indent(snippet, 2)}\n"
|
72
|
+
end
|
73
|
+
|
74
|
+
template(
|
75
|
+
'hoboken/templates/spec/example_worker_spec.rb.tt',
|
76
|
+
'spec/example_worker_spec.rb'
|
77
|
+
)
|
78
|
+
end
|
79
|
+
# rubocop:enable Metrics/MethodLength
|
80
|
+
|
81
|
+
def add_worker_to_procfile
|
82
|
+
append_file('Procfile') do
|
83
|
+
"\nworker: bundle exec sidekiq " \
|
84
|
+
'-r ./config/sidekiq.rb ' \
|
85
|
+
'-e $RACK_ENV ' \
|
86
|
+
'-c ${MAX_THREADS:-5} ' \
|
87
|
+
"-v\n"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
# rubocop:disable Metrics/MethodLength
|
92
|
+
def update_readme
|
93
|
+
snippet = <<~CODE
|
94
|
+
<tr>
|
95
|
+
<td>REDIS_URL</td>
|
96
|
+
<td>Yes</td>
|
97
|
+
<td>localhost:6379</td>
|
98
|
+
<td>Redis connection URL</td>
|
99
|
+
</tr>
|
100
|
+
<tr>
|
101
|
+
<td>SIDEKIQ_PASSWORD</td>
|
102
|
+
<td>Production Only</td>
|
103
|
+
<td>None</td>
|
104
|
+
<td>Password for SidekiqUI Basic Auth</td>
|
105
|
+
</tr>
|
106
|
+
<tr>
|
107
|
+
<td>SIDEKIQ_USERNAME</td>
|
108
|
+
<td>Production Only</td>
|
109
|
+
<td>None</td>
|
110
|
+
<td>Username for SidekiqUI Basic Auth</td>
|
111
|
+
</tr>
|
112
|
+
CODE
|
113
|
+
|
114
|
+
insert_into_file('README.md', after: /<tbody>\n/) do
|
115
|
+
indent(snippet, 8)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
# rubocop:enable Metrics/MethodLength
|
119
|
+
|
120
|
+
def reminders
|
121
|
+
text = <<~TEXT
|
122
|
+
|
123
|
+
Gemfile updated... don't forget to 'bundle install'
|
124
|
+
|
125
|
+
You can configure a Sidekiq error handing service in `config/sidekiq.rb`.
|
126
|
+
|
127
|
+
Sidekiq UI is available at '/sidekiq'. In production environments
|
128
|
+
the UI is protected with HTTP Basic Auth. Don't forget to set
|
129
|
+
`SIDEKIQ_USERNAME` and `SIDEKIQ_PASSWORD` in your production
|
130
|
+
environment or you won't be able to access the Sidekiq UI.
|
131
|
+
TEXT
|
132
|
+
|
133
|
+
say text, :green
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Hoboken
|
4
|
+
module AddOns
|
5
|
+
# Gherkin extension for RSpec
|
6
|
+
#
|
7
|
+
class Turnip < ::Hoboken::Group
|
8
|
+
def add_gems
|
9
|
+
return unless rspec?
|
10
|
+
|
11
|
+
gem 'turnip', version: '4.3', group: :test
|
12
|
+
end
|
13
|
+
|
14
|
+
# rubocop:disable Metrics/MethodLength
|
15
|
+
def add_sample_files
|
16
|
+
return unless rspec?
|
17
|
+
|
18
|
+
empty_directory('spec/features')
|
19
|
+
empty_directory('spec/support/steps')
|
20
|
+
create_file('spec/features/example.feature') do
|
21
|
+
<<~TEXT
|
22
|
+
@feature
|
23
|
+
Feature: An Example
|
24
|
+
This is an example feature spec that can be deleted.
|
25
|
+
|
26
|
+
Scenario: Name of some scenario
|
27
|
+
Given nothing
|
28
|
+
When I do nothing
|
29
|
+
Then nothing should happen
|
30
|
+
TEXT
|
31
|
+
end
|
32
|
+
|
33
|
+
create_file('spec/support/steps/example_steps.rb') do
|
34
|
+
<<~CODE
|
35
|
+
# frozen_string_literal: true
|
36
|
+
|
37
|
+
# Steps for the example feature that can be deleted.
|
38
|
+
|
39
|
+
step 'nothing' do
|
40
|
+
# ...
|
41
|
+
end
|
42
|
+
|
43
|
+
step 'I do nothing' do
|
44
|
+
# ...
|
45
|
+
end
|
46
|
+
|
47
|
+
step 'nothing should happen' do
|
48
|
+
# ...
|
49
|
+
end
|
50
|
+
CODE
|
51
|
+
end
|
52
|
+
end
|
53
|
+
# rubocop:enable Metrics/MethodLength
|
54
|
+
|
55
|
+
def add_helper
|
56
|
+
return unless rspec?
|
57
|
+
|
58
|
+
template(
|
59
|
+
'hoboken/templates/spec/turnip_helper.rb.tt',
|
60
|
+
'spec/turnip_helper.rb'
|
61
|
+
)
|
62
|
+
end
|
63
|
+
|
64
|
+
def rake_task
|
65
|
+
return unless rspec?
|
66
|
+
|
67
|
+
create_file('tasks/turnip.rake') do
|
68
|
+
<<~TEXT
|
69
|
+
# frozen_string_literal: true
|
70
|
+
|
71
|
+
require 'rspec/core/rake_task'
|
72
|
+
|
73
|
+
desc 'Run turnip acceptance tests'
|
74
|
+
RSpec::Core::RakeTask.new(:turnip) do |t|
|
75
|
+
t.pattern = './spec{,/*/**}/*.feature'
|
76
|
+
t.rspec_opts = ['-r turnip/rspec']
|
77
|
+
end
|
78
|
+
TEXT
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def default_rake_task
|
83
|
+
return unless rspec?
|
84
|
+
|
85
|
+
gsub_file('Rakefile', /task default:.*/, 'task default: %w[spec turnip]')
|
86
|
+
end
|
87
|
+
|
88
|
+
def ci_task
|
89
|
+
return unless rspec?
|
90
|
+
|
91
|
+
gsub_file('Rakefile', /task ci:.*/) do |match|
|
92
|
+
if match.include?('rubocop')
|
93
|
+
'task ci: %w[spec turnip rubocop]'
|
94
|
+
else
|
95
|
+
'task ci: %w[spec turnip]'
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def reminders
|
101
|
+
if rspec?
|
102
|
+
say "Gemfile updated... don't forget to 'bundle install'", :green
|
103
|
+
else
|
104
|
+
say 'Turnip requires RSpec to be setup', :red
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Hoboken
|
4
|
+
module AddOns
|
5
|
+
# Twitter Bootstrap support.
|
6
|
+
#
|
7
|
+
class TwitterBootstrap < ::Hoboken::Group
|
8
|
+
def add_gem
|
9
|
+
gem 'bootstrap', version: '5.0.0.beta3', group: :assets
|
10
|
+
end
|
11
|
+
|
12
|
+
def update_app
|
13
|
+
indentation = classic? ? 2 : 6
|
14
|
+
location = /configure do\n/
|
15
|
+
insert_into_file('config/environment.rb', after: location) do
|
16
|
+
indent("require 'bootstrap'\n", indentation)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def update_asset_files
|
21
|
+
prepend_file('assets/stylesheets/styles.scss') do
|
22
|
+
<<~CODE
|
23
|
+
@import "bootstrap";
|
24
|
+
|
25
|
+
CODE
|
26
|
+
end
|
27
|
+
|
28
|
+
prepend_file('assets/javascripts/app.js') do
|
29
|
+
<<~CODE
|
30
|
+
//= require popper
|
31
|
+
//= require bootstrap-sprockets
|
32
|
+
CODE
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def remove_normalize_css
|
37
|
+
gsub_file(
|
38
|
+
'views/layout.erb',
|
39
|
+
'<link rel="stylesheet" type="text/css" ' \
|
40
|
+
'href="//cdnjs.cloudflare.com/ajax/libs/normalize/2.1.3/normalize.min.css">',
|
41
|
+
''
|
42
|
+
)
|
43
|
+
end
|
44
|
+
|
45
|
+
def reminders
|
46
|
+
say "\nGemfile updated... don't forget to 'bundle install'"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Hoboken
|
4
|
+
module AddOns
|
5
|
+
# Record your test suite's HTTP interactions and replay them during
|
6
|
+
# future test runs.
|
7
|
+
#
|
8
|
+
class Vcr < ::Hoboken::Group
|
9
|
+
def add_gems
|
10
|
+
gem 'vcr', version: '6.0', group: :test
|
11
|
+
gem 'webmock', version: '3.13', group: :test
|
12
|
+
end
|
13
|
+
|
14
|
+
def add_directories
|
15
|
+
empty_directory(File.join(location, 'fixtures', 'vcr_cassettes'))
|
16
|
+
end
|
17
|
+
|
18
|
+
def add_setup_file
|
19
|
+
template(
|
20
|
+
'hoboken/templates/vcr_setup.rb.tt',
|
21
|
+
File.join(location, 'support/vcr_setup.rb')
|
22
|
+
)
|
23
|
+
end
|
24
|
+
|
25
|
+
def require_vcr_in_test_helper
|
26
|
+
return if rspec?
|
27
|
+
|
28
|
+
snippet_location = "require_relative 'support/rack_helpers'"
|
29
|
+
insert_into_file('test/test_helper.rb', after: snippet_location) do
|
30
|
+
"\nrequire_relative 'support/vcr_setup'"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def require_vcr_in_spec_helper
|
35
|
+
return unless rspec?
|
36
|
+
|
37
|
+
snippet_location = "require 'support/rack_helpers'"
|
38
|
+
insert_into_file('spec/spec_helper.rb', after: snippet_location) do
|
39
|
+
"\nrequire 'support/vcr_setup'"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def reminders
|
44
|
+
say "Gemfile updated... don't forget to 'bundle install'", :green
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def location
|
50
|
+
rspec? ? 'spec' : 'test'
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
data/lib/hoboken/generate.rb
CHANGED
@@ -1,111 +1,197 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rbconfig'
|
2
4
|
|
3
5
|
module Hoboken
|
6
|
+
# Main project generator.
|
7
|
+
#
|
8
|
+
# rubocop:disable Metrics/ClassLength
|
4
9
|
class Generate < Thor::Group
|
5
10
|
include Thor::Actions
|
6
11
|
|
7
|
-
NULL = RbConfig::CONFIG['host_os']
|
12
|
+
NULL = RbConfig::CONFIG['host_os'].match?(/mingw|mswin/) ? 'NUL' : '/dev/null'
|
8
13
|
|
9
14
|
argument :name
|
10
15
|
|
11
16
|
class_option :ruby_version,
|
12
17
|
type: :string,
|
13
|
-
desc:
|
18
|
+
desc: 'Ruby version for Gemfile',
|
14
19
|
default: RUBY_VERSION
|
15
20
|
|
16
21
|
class_option :tiny,
|
17
22
|
type: :boolean,
|
18
|
-
desc:
|
23
|
+
desc: 'Generate views inline; do not create /public folder',
|
19
24
|
default: false
|
20
25
|
|
21
26
|
class_option :type,
|
22
27
|
type: :string,
|
23
|
-
desc:
|
28
|
+
desc: 'Architecture type (classic or modular)',
|
24
29
|
default: :classic
|
25
30
|
|
26
31
|
class_option :git,
|
27
32
|
type: :boolean,
|
28
|
-
desc:
|
33
|
+
desc: 'Create a Git repository and make initial commit',
|
34
|
+
default: false
|
35
|
+
|
36
|
+
class_option :api_only,
|
37
|
+
type: :boolean,
|
38
|
+
desc: 'API only, no views, public folder, etc.',
|
29
39
|
default: false
|
30
40
|
|
41
|
+
class_option :test_framework,
|
42
|
+
type: :string,
|
43
|
+
desc: 'Testing framework; can be either test-unit or rspec',
|
44
|
+
default: 'test-unit'
|
45
|
+
|
31
46
|
def self.source_root
|
32
47
|
File.dirname(__FILE__)
|
33
48
|
end
|
34
49
|
|
35
50
|
def app_folder
|
36
51
|
empty_directory(snake_name)
|
37
|
-
apply_template(
|
38
|
-
apply_template(
|
39
|
-
apply_template(
|
40
|
-
apply_template(
|
41
|
-
apply_template(
|
52
|
+
apply_template('classic.rb.tt', 'app.rb')
|
53
|
+
apply_template('Gemfile.erb.tt', 'Gemfile')
|
54
|
+
apply_template('config.ru.tt', 'config.ru')
|
55
|
+
apply_template('README.md.tt', 'README.md')
|
56
|
+
apply_template('Rakefile.tt', 'Rakefile')
|
57
|
+
|
58
|
+
create_file("#{snake_name}/Procfile") do
|
59
|
+
'web: bundle exec puma -C config/puma.rb'
|
60
|
+
end
|
42
61
|
end
|
43
62
|
|
44
|
-
def
|
45
|
-
empty_directory("#{snake_name}/
|
46
|
-
|
47
|
-
|
63
|
+
def bin_folder
|
64
|
+
empty_directory("#{snake_name}/bin")
|
65
|
+
%w[console server setup].each do |f|
|
66
|
+
target = "#{snake_name}/bin/#{f}"
|
67
|
+
copy_file("templates/#{f}", target)
|
68
|
+
chmod(target, 0o755)
|
69
|
+
end
|
48
70
|
end
|
49
71
|
|
50
|
-
def
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
72
|
+
def config_folder
|
73
|
+
empty_directory("#{snake_name}/config")
|
74
|
+
apply_template('puma.rb.tt', 'config/puma.rb')
|
75
|
+
apply_template('classic_environment.rb.tt', 'config/environment.rb')
|
76
|
+
end
|
55
77
|
|
56
|
-
|
57
|
-
|
78
|
+
def view_folder
|
79
|
+
return if options[:api_only]
|
80
|
+
|
81
|
+
empty_directory("#{snake_name}/views")
|
82
|
+
apply_template('views/layout.erb.tt', 'views/layout.erb')
|
83
|
+
apply_template('views/index.erb.tt', 'views/index.erb')
|
58
84
|
end
|
59
85
|
|
60
|
-
def
|
61
|
-
return if options[:
|
86
|
+
def asset_pipeline
|
87
|
+
return if options[:api_only]
|
88
|
+
|
62
89
|
inside snake_name do
|
63
|
-
empty_directory(
|
64
|
-
|
90
|
+
empty_directory('assets')
|
91
|
+
empty_directory('public')
|
92
|
+
%w[stylesheets images javascripts].each { |f| empty_directory("assets/#{f}") }
|
65
93
|
end
|
66
|
-
apply_template("styles.css.tt", "public/css/styles.css")
|
67
|
-
create_file("#{snake_name}/public/js/app.js", "")
|
68
94
|
|
69
|
-
|
70
|
-
|
95
|
+
apply_template('styles.css.tt', 'assets/stylesheets/styles.scss')
|
96
|
+
create_file("#{snake_name}/assets/javascripts/app.js", '')
|
97
|
+
|
98
|
+
%w[favicon hoboken sinatra].each do |f|
|
99
|
+
copy_file("templates/#{f}.png", "#{snake_name}/assets/images/#{f}.png")
|
71
100
|
end
|
72
101
|
end
|
73
102
|
|
74
103
|
def test_folder
|
104
|
+
return unless 'test-unit' == options[:test_framework]
|
105
|
+
|
75
106
|
empty_directory("#{snake_name}/test/unit")
|
107
|
+
empty_directory("#{snake_name}/test/integration")
|
76
108
|
empty_directory("#{snake_name}/test/support")
|
77
|
-
apply_template(
|
78
|
-
apply_template(
|
79
|
-
apply_template(
|
109
|
+
apply_template('test_unit.rake.tt', 'tasks/test_unit.rake')
|
110
|
+
apply_template('test/test_helper.rb.tt', 'test/test_helper.rb')
|
111
|
+
apply_template('test/unit/app_test.rb.tt', 'test/unit/app_test.rb')
|
112
|
+
apply_template('support/rack_helpers.rb.tt', 'test/support/rack_helpers.rb')
|
113
|
+
apply_template('support/rack_test_assertions.rb.tt',
|
114
|
+
'test/support/rack_test_assertions.rb')
|
115
|
+
end
|
116
|
+
|
117
|
+
def rspec_setup
|
118
|
+
return unless 'rspec' == options[:test_framework]
|
119
|
+
|
120
|
+
empty_directory("#{snake_name}/spec")
|
121
|
+
empty_directory("#{snake_name}/spec/support")
|
122
|
+
create_file("#{snake_name}/.rspec") { '--require spec_helper' }
|
123
|
+
apply_template('rspec.rake.tt', 'tasks/rspec.rake')
|
124
|
+
apply_template('spec/app_spec.rb.tt', 'spec/app_spec.rb')
|
125
|
+
apply_template('spec/spec_helper.rb.tt', 'spec/spec_helper.rb')
|
126
|
+
apply_template('support/rack_helpers.rb.tt', 'spec/support/rack_helpers.rb')
|
127
|
+
apply_template('spec/rack_matchers.rb.tt', 'spec/support/rack_matchers.rb')
|
128
|
+
end
|
129
|
+
|
130
|
+
def env_file
|
131
|
+
inside snake_name do
|
132
|
+
create_file('.env') do
|
133
|
+
"RACK_ENV=development\nPORT=9292\nSESSION_SECRET=secret"
|
134
|
+
end
|
135
|
+
end
|
80
136
|
end
|
81
137
|
|
138
|
+
# rubocop:disable Metrics/AbcSize
|
82
139
|
def make_modular
|
83
|
-
return unless
|
140
|
+
return unless 'modular' == options[:type]
|
141
|
+
|
84
142
|
empty_directory("#{snake_name}/helpers")
|
85
143
|
remove_file("#{snake_name}/app.rb")
|
86
|
-
|
87
|
-
|
144
|
+
remove_file("#{snake_name}/config/environment.rb")
|
145
|
+
apply_template('modular.rb.tt', 'app.rb')
|
146
|
+
apply_template('modular_environment.rb.tt', 'config/environment.rb')
|
147
|
+
|
148
|
+
files = [].tap do |f|
|
149
|
+
f << 'config.ru'
|
150
|
+
f << 'test/support/rack_helpers.rb' if 'test-unit' == options[:test_framework]
|
151
|
+
f << 'spec/support/rack_helpers.rb' if 'rspec' == options[:test_framework]
|
152
|
+
end
|
153
|
+
|
154
|
+
files.each do |f|
|
88
155
|
path = File.join(snake_name, f)
|
89
156
|
gsub_file(path, /Sinatra::Application/, "#{camel_name}::App")
|
90
157
|
end
|
91
158
|
end
|
159
|
+
# rubocop:enable Metrics/AbcSize
|
160
|
+
|
161
|
+
def inline_views
|
162
|
+
return unless options[:tiny]
|
163
|
+
return if options[:api_only]
|
164
|
+
|
165
|
+
combined_views = %w[layout index].map { |f|
|
166
|
+
"@@#{f}\n" + File.read("#{snake_name}/views/#{f}.erb")
|
167
|
+
}.join("\n")
|
168
|
+
|
169
|
+
append_to_file("#{snake_name}/app.rb", "\n__END__\n\n#{combined_views}")
|
170
|
+
remove_dir("#{snake_name}/views")
|
171
|
+
end
|
92
172
|
|
93
173
|
def create_git_repository
|
94
174
|
return unless options[:git]
|
95
|
-
|
96
|
-
|
175
|
+
|
176
|
+
if git?
|
177
|
+
copy_file('templates/gitignore', "#{snake_name}/.gitignore")
|
97
178
|
inside snake_name do
|
98
|
-
run(
|
99
|
-
run(
|
100
|
-
run(
|
179
|
+
run('git init .')
|
180
|
+
run('git add .')
|
181
|
+
run('git commit -m "Initial commit."')
|
101
182
|
end
|
102
183
|
else
|
103
|
-
say "\nYou asked that a Git repository be created for the
|
184
|
+
say "\nYou asked that a Git repository be created for the " \
|
185
|
+
'project, but no Git executable could be found.'
|
104
186
|
end
|
105
187
|
end
|
106
188
|
|
107
189
|
def directions
|
108
|
-
say "\nSuccessfully created #{name}.
|
190
|
+
say "\nSuccessfully created #{name}."
|
191
|
+
end
|
192
|
+
|
193
|
+
def self.exit_on_failure?
|
194
|
+
true
|
109
195
|
end
|
110
196
|
|
111
197
|
private
|
@@ -115,19 +201,33 @@ module Hoboken
|
|
115
201
|
end
|
116
202
|
|
117
203
|
def camel_name
|
118
|
-
Thor::Util.camel_case(name)
|
204
|
+
Thor::Util.camel_case(name.split('/').last)
|
119
205
|
end
|
120
206
|
|
121
207
|
def titleized_name
|
122
|
-
snake_name.split(
|
208
|
+
snake_name.split('_').map(&:capitalize).join(' ')
|
123
209
|
end
|
124
210
|
|
125
211
|
def author
|
126
|
-
|
212
|
+
if git?
|
213
|
+
`git config user.name`.chomp
|
214
|
+
else
|
215
|
+
say "\nNo Git executable found. Using result of `whoami` as author name."
|
216
|
+
`whoami`.chomp
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
def git?
|
221
|
+
system("git --version >#{NULL} 2>&1")
|
127
222
|
end
|
128
223
|
|
129
224
|
def apply_template(src, dest)
|
130
225
|
template("templates/#{src}", "#{snake_name}/#{dest}")
|
131
226
|
end
|
227
|
+
|
228
|
+
def ruby_three_one_or_greater?
|
229
|
+
Gem::Version.new(RUBY_VERSION).release >= Gem::Version.new('3.1')
|
230
|
+
end
|
132
231
|
end
|
232
|
+
# rubocop:enable Metrics/ClassLength
|
133
233
|
end
|