hoboken 0.0.1 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +5 -5
  2. data/.github/dependabot.yml +7 -0
  3. data/.github/workflows/ruby.yml +28 -0
  4. data/.rubocop.yml +33 -0
  5. data/.ruby-version +1 -0
  6. data/Gemfile +2 -0
  7. data/IDEAS.md +57 -0
  8. data/LICENSE.txt +1 -1
  9. data/README.md +21 -10
  10. data/Rakefile +14 -6
  11. data/bin/hoboken +2 -1
  12. data/hoboken.gemspec +53 -16
  13. data/lib/hoboken.rb +110 -23
  14. data/lib/hoboken/actions.rb +10 -6
  15. data/lib/hoboken/add_ons/github_action.rb +14 -0
  16. data/lib/hoboken/add_ons/heroku.rb +8 -23
  17. data/lib/hoboken/add_ons/internationalization.rb +10 -6
  18. data/lib/hoboken/add_ons/metrics.rb +39 -14
  19. data/lib/hoboken/add_ons/omniauth.rb +114 -47
  20. data/lib/hoboken/add_ons/rubocop.rb +40 -0
  21. data/lib/hoboken/add_ons/sequel.rb +76 -47
  22. data/lib/hoboken/add_ons/sprockets.rb +67 -65
  23. data/lib/hoboken/add_ons/travis.rb +6 -2
  24. data/lib/hoboken/add_ons/twbs.rb +80 -0
  25. data/lib/hoboken/generate.rb +112 -38
  26. data/lib/hoboken/templates/Gemfile.erb.tt +33 -10
  27. data/lib/hoboken/templates/README.md.tt +105 -35
  28. data/lib/hoboken/templates/Rakefile.tt +10 -22
  29. data/lib/hoboken/templates/classic.rb.tt +35 -8
  30. data/lib/hoboken/templates/config.ru.tt +5 -3
  31. data/lib/hoboken/templates/console.sh +5 -0
  32. data/lib/hoboken/templates/db.rb.tt +24 -0
  33. data/lib/hoboken/templates/github_action.tt +28 -0
  34. data/lib/hoboken/templates/gitignore +8 -1
  35. data/lib/hoboken/templates/metrics.rake.tt +10 -9
  36. data/lib/hoboken/templates/modular.rb.tt +40 -11
  37. data/lib/hoboken/templates/puma.rb.tt +21 -0
  38. data/lib/hoboken/templates/rspec.rake.tt +5 -0
  39. data/lib/hoboken/templates/rubocop.yml.tt +31 -0
  40. data/lib/hoboken/templates/sequel.rake +6 -4
  41. data/lib/hoboken/templates/server.sh +12 -0
  42. data/lib/hoboken/templates/setup.sh +7 -0
  43. data/lib/hoboken/templates/spec/app_spec.rb.tt +15 -0
  44. data/lib/hoboken/templates/spec/rack_matchers.rb.tt +56 -0
  45. data/lib/hoboken/templates/spec/spec_helper.rb.tt +41 -0
  46. data/lib/hoboken/templates/sprockets.rake +13 -7
  47. data/lib/hoboken/templates/sprockets_chain.rb +7 -3
  48. data/lib/hoboken/templates/sprockets_helper.rb +14 -10
  49. data/lib/hoboken/templates/support/rack_helpers.rb.tt +55 -0
  50. data/lib/hoboken/templates/support/rack_test_assertions.rb.tt +111 -0
  51. data/lib/hoboken/templates/test/test_helper.rb.tt +38 -27
  52. data/lib/hoboken/templates/test/unit/app_test.rb.tt +11 -3
  53. data/lib/hoboken/templates/test_unit.rake.tt +18 -0
  54. data/lib/hoboken/templates/views/index.erb.tt +10 -3
  55. data/lib/hoboken/templates/views/layout.erb.tt +4 -1
  56. data/lib/hoboken/version.rb +3 -1
  57. data/test/fixtures/Gemfile +3 -3
  58. data/test/fixtures/Gemfile.pristine +3 -2
  59. data/test/integration/add_on_test.rb +399 -136
  60. data/test/integration/generate_test.rb +170 -38
  61. data/test/test_helper.rb +54 -23
  62. data/test/unit/hoboken_actions_test.rb +70 -61
  63. metadata +441 -16
  64. data/.travis.yml +0 -5
  65. data/lib/hoboken/templates/test/support/rack_test_assertions.rb.tt +0 -92
@@ -1,79 +1,108 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Hoboken
2
4
  module AddOns
5
+ # Database access via Sequel gem.
6
+ #
3
7
  class Sequel < ::Hoboken::Group
4
8
  def add_gems
5
- gem "sequel", version: "4.6.0"
6
- gem "sqlite3", version: "1.3.8", group: [:development, :test]
9
+ gem 'sequel', version: '5.43'
10
+ gem 'sqlite3', version: '1.4', group: %i[development test]
7
11
  end
8
12
 
9
13
  def setup_directories
10
- empty_directory("db/migrate")
11
- empty_directory("tasks")
14
+ empty_directory('db/migrate')
15
+ empty_directory('tasks')
16
+ empty_directory('tmp')
12
17
  end
13
18
 
14
19
  def copy_rake_task
15
- copy_file("hoboken/templates/sequel.rake", "tasks/sequel.rake")
20
+ copy_file('hoboken/templates/sequel.rake', 'tasks/sequel.rake')
21
+ end
22
+
23
+ def setup_db_config
24
+ template('hoboken/templates/db.rb.tt', 'config/db.rb')
16
25
  end
17
26
 
18
- def setup_database_connection_in_rackup_file
19
- insert_into_file("config.ru", after: /require "bundler\/setup"/) do
20
- "\nrequire \"logger\"\nrequire \"sequel\""
27
+ def require_db_config
28
+ location = classic? ? 'configure do' : 'module'
29
+ insert_into_file('app.rb', before: location) do
30
+ "require_relative 'config/db'\n\n"
21
31
  end
32
+ end
22
33
 
23
- app_name = File.open("config.ru").grep(/run.+/).first.chomp.gsub("run ", "")
34
+ def setup_puma_config
35
+ insert_into_file('config/puma.rb', after: 'before_fork do') do
36
+ "\n DB.disconnect if defined?(DB)"
37
+ end
38
+ end
24
39
 
25
- gsub_file("config.ru", /run #{app_name}/) do
26
- <<CODE
40
+ # rubocop:disable Metrics/MethodLength
41
+ def add_database_test_helper_class
42
+ return if rspec?
27
43
 
28
- db = Sequel.connect(ENV["DATABASE_URL"], loggers: [Logger.new($stdout)])
29
- Sequel.extension :migration
30
- Sequel::Migrator.check_current(db, "db/migrate") if Dir.glob("db/migrate/*.rb").size > 0
44
+ insert_into_file('test/test_helper.rb', before: /ENV\['RACK_ENV'\] = 'test'/) do
45
+ "ENV['DATABASE_URL'] = 'sqlite://db/test.db'\n"
46
+ end
31
47
 
32
- app = #{app_name}
33
- app.set :database, db
34
- run app
35
- CODE
48
+ insert_into_file('test/test_helper.rb', after: %r{require 'test/unit'}) do
49
+ "\nrequire 'sequel'"
36
50
  end
37
- end
38
51
 
39
- def add_database_test_helper_class
40
- insert_into_file("test/test_helper.rb", after: /require "test\/unit"/) do
41
- "\nrequire \"sequel\""
52
+ append_file('test/test_helper.rb') do
53
+ <<~CODE
54
+
55
+ module Test
56
+ module Database
57
+ class TestCase < Test::Unit::TestCase
58
+ def run(*args, &block)
59
+ result = nil
60
+ DB.transaction(rollback: :always) { result = super }
61
+ result
62
+ end
63
+ end
64
+ end
65
+ end
66
+ CODE
42
67
  end
68
+ end
69
+ # rubocop:enable Metrics/MethodLength
43
70
 
44
- append_file("test/test_helper.rb") do
45
- <<CODE
71
+ # rubocop:disable Metrics/MethodLength
72
+ def add_database_spec_helper
73
+ return unless rspec?
46
74
 
47
- module Test::Database
48
- class TestCase < Test::Unit::TestCase
49
- def run(*args, &block)
50
- result = nil
51
- database.transaction(rollback: :always) { result = super }
52
- result
53
- end
75
+ insert_into_file('spec/spec_helper.rb', before: /ENV\['RACK_ENV'\] = 'test'/) do
76
+ "ENV['DATABASE_URL'] = 'sqlite://db/test.db'\n"
77
+ end
54
78
 
55
- private
79
+ snippet_rack = <<~CODE
80
+ config.around(:example, rack: true) do |example|
81
+ DB.transaction(rollback: :always) { example.run }
82
+ end
83
+ CODE
56
84
 
57
- def database
58
- @database ||= Sequel.sqlite.tap do |db|
59
- Sequel.extension :migration
60
- Sequel::Migrator.run(db, 'db/migrate') if Dir.glob("db/migrate/*.rb").size > 0
61
- end
62
- end
63
- end
64
- end
65
- CODE
85
+ snippet_database = <<~CODE
86
+ config.around(:example, database: true) do |example|
87
+ DB.transaction(rollback: :always) { example.run }
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_rack, 2)}\n#{indent(snippet_database, 2)}\n"
66
94
  end
67
95
  end
96
+ # rubocop:enable Metrics/MethodLength
68
97
 
69
98
  def reminders
70
99
  say "\nGemfile updated... don't forget to 'bundle install'"
71
- say <<TEXT
72
-
73
- Notes:
74
- * The sqlite3 gem has been installed for dev and test environments only. You will need to specify a gem to use for production.
75
- * You will need to specify an environment variable 'DATABASE_URL' (either add it to .env or export it)
76
- TEXT
100
+ say <<~TEXT
101
+ #{' '}
102
+ Notes:
103
+ * The sqlite3 gem has been installed for dev and test environments only. You will need to specify a gem to use for production.
104
+ * You will need to specify an environment variable 'DATABASE_URL' (either add it to .env or export it)
105
+ TEXT
77
106
  end
78
107
  end
79
108
  end
@@ -1,97 +1,99 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Hoboken
2
4
  module AddOns
5
+ # Rack-based asset packaging system.
6
+ #
3
7
  class Sprockets < ::Hoboken::Group
4
8
  def create_assets_folder
5
- empty_directory("assets")
6
- FileUtils.cp("public/css/styles.css", "assets/styles.css")
7
- FileUtils.cp("public/js/app.js", "assets/app.js")
9
+ empty_directory('assets')
10
+ FileUtils.cp('public/css/styles.css', 'assets/styles.scss')
11
+ FileUtils.cp('public/js/app.js', 'assets/app.js')
8
12
  end
9
13
 
10
14
  def add_gems
11
- gem "sprockets", version: "2.10.0", group: :assets
12
- gem "uglifier", version: "2.1.1", group: :assets
13
- gem "yui-compressor", version: "0.9.6", group: :assets
15
+ gem 'sassc', version: '2.4', group: :assets
16
+ gem 'sprockets', version: '4.0', group: :assets
17
+ gem 'uglifier', version: '4.2', group: :assets
18
+ gem 'yui-compressor', version: '0.12', group: :assets
14
19
  end
15
20
 
16
21
  def copy_sprockets_helpers
17
- copy_file("hoboken/templates/sprockets.rake", "tasks/sprockets.rake")
18
- copy_file("hoboken/templates/sprockets_chain.rb", "middleware/sprockets_chain.rb")
19
- copy_file("hoboken/templates/sprockets_helper.rb", "helpers/sprockets.rb")
22
+ copy_file('hoboken/templates/sprockets.rake', 'tasks/sprockets.rake')
23
+ copy_file('hoboken/templates/sprockets_chain.rb', 'middleware/sprockets_chain.rb')
24
+ copy_file('hoboken/templates/sprockets_helper.rb', 'helpers/sprockets.rb')
20
25
  end
21
26
 
22
27
  def update_app
23
- insert_into_file("app.rb", after: /configure :development do\n/) do
24
- <<CODE
25
- require File.expand_path('middleware/sprockets_chain', settings.root)
26
- use Middleware::SprocketsChain, %r{/assets} do |env|
27
- %w(assets vendor).each do |f|
28
- env.append_path File.expand_path("../\#{f}", __FILE__)
29
- end
30
- end
31
-
32
- CODE
28
+ snippet = <<~CODE
29
+ require File.expand_path('middleware/sprockets_chain', settings.root)
30
+ use Middleware::SprocketsChain, %r{/assets} do |env|
31
+ %w[assets vendor].each do |f|
32
+ env.append_path File.expand_path("../\#{f}", __FILE__)
33
+ end
34
+ end
35
+ CODE
36
+
37
+ indentation = classic? ? 2 : 6
38
+ insert_into_file('app.rb', after: /configure :development do\n/) do
39
+ "#{indent(snippet, indentation)}\n"
33
40
  end
34
41
 
35
- insert_into_file("app.rb", after: /set :root, File.dirname\(__FILE__\)\n/) do
36
- " helpers Helpers::Sprockets"
37
- end
38
-
39
- gsub_file("app.rb", /require "sinatra\/reloader" if development\?/) do
40
- <<CODE
41
- if development?
42
- require "sinatra/reloader"
43
-
44
- require File.expand_path('middleware/sprockets_chain', settings.root)
45
- use Middleware::SprocketsChain, %r{/assets} do |env|
46
- %w(assets vendor).each do |f|
47
- env.append_path File.expand_path("../\#{f}", __FILE__)
48
- end
49
- end
50
- end
51
-
52
- helpers Helpers::Sprockets
53
- CODE
42
+ insert_into_file('app.rb', after: /configure do\n/) do
43
+ "#{indent("helpers Helpers::Sprockets\n", indentation)}\n"
54
44
  end
55
45
  end
56
46
 
47
+ # rubocop:disable Metrics/MethodLength
57
48
  def adjust_link_tags
58
- insert_into_file("views/layout.erb", before: /<\/head>/) do
59
- <<HTML
60
- <%= stylesheet_tag :styles %>
61
-
62
- <%= javascript_tag :app %>
49
+ insert_into_file('views/layout.erb', before: %r{</head>}) do
50
+ <<HTML
51
+ <%== stylesheet_tag :styles %>
52
+ <%== javascript_tag :app %>
63
53
  HTML
64
54
  end
65
55
 
66
- gsub_file("views/layout.erb", /<link rel="stylesheet" type="text\/css" href="css\/styles.css">/, "")
67
- gsub_file("views/layout.erb", /<script type="text\/javascript" src="js\/app.js"><\/script>/, "")
56
+ gsub_file(
57
+ 'views/layout.erb',
58
+ %r{<link rel="stylesheet" type="text/css" href="css/styles.css">},
59
+ ''
60
+ )
61
+
62
+ gsub_file(
63
+ 'views/layout.erb',
64
+ %r{<script type="text/javascript" src="js/app.js"></script>},
65
+ ''
66
+ )
68
67
  end
68
+ # rubocop:enable Metrics/MethodLength
69
69
 
70
+ # rubocop:disable Metrics/MethodLength
70
71
  def directions
71
- text = <<TEXT
72
-
73
- Run `bundle install` to get the sprockets gem and its
74
- dependencies.
75
-
76
- Running the server in development mode will serve css
77
- and js files from /assets. In order to serve assets in
78
- production, you must run `rake assets:precompile`. Read
79
- the important note below before running this rake task.
80
- TEXT
81
-
82
- important = <<TEXT
83
-
84
- Important Note:
85
- Any css or js files from the /public folder have been copied
86
- to /assets, the original files remain intact in /public, but
87
- will be replaced the first time you run `rake assets:precompile`.
88
- You may want to backup those files if they are not under source
89
- control before running the Rake command.
90
- TEXT
72
+ text = <<~TEXT
73
+ #{' '}
74
+ Run `bundle install` to get the sprockets gem and its
75
+ dependencies.
76
+ #{' '}
77
+ Running the server in development mode will serve css
78
+ and js files from /assets. In order to serve assets in
79
+ production, you must run `rake assets:precompile`. Read
80
+ the important note below before running this rake task.
81
+ TEXT
82
+
83
+ important = <<~TEXT
84
+ #{' '}
85
+ Important Note:
86
+ Any css or js files from the /public folder have been copied
87
+ to /assets, the original files remain intact in /public, but
88
+ will be replaced the first time you run `rake assets:precompile`.
89
+ You may want to backup those files if they are not under source
90
+ control before running the Rake command.
91
+ TEXT
91
92
 
92
93
  say text
93
94
  say important, :red
94
95
  end
96
+ # rubocop:enable Metrics/MethodLength
95
97
  end
96
98
  end
97
99
  end
@@ -1,9 +1,13 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Hoboken
2
4
  module AddOns
5
+ # Basic Travis-CI YAML config.
6
+ #
3
7
  class Travis < ::Hoboken::Group
4
8
  def travis_yml
5
- create_file(".travis.yml") do
6
- "language: ruby"
9
+ create_file('.travis.yml') do
10
+ 'language: ruby'
7
11
  end
8
12
  end
9
13
  end
@@ -0,0 +1,80 @@
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
+ return unless sprockets?
10
+
11
+ gem 'bootstrap', version: '5.0.0.beta3', group: :assets
12
+ end
13
+
14
+ def update_app
15
+ return unless sprockets?
16
+
17
+ indentation = classic? ? 2 : 6
18
+ insert_into_file('app.rb', after: /require.*sprockets_chain.*\n/) do
19
+ indent("require 'bootstrap'\n", indentation)
20
+ end
21
+ end
22
+
23
+ def update_asset_files
24
+ return unless sprockets?
25
+
26
+ prepend_file('assets/styles.scss') do
27
+ <<~CODE
28
+ @import "bootstrap";
29
+
30
+ CODE
31
+ end
32
+
33
+ prepend_file('assets/app.js') do
34
+ <<~CODE
35
+ //= require popper
36
+ //= require bootstrap-sprockets
37
+ CODE
38
+ end
39
+ end
40
+
41
+ def update_sprockets_rake_tasks
42
+ return unless sprockets?
43
+
44
+ insert_into_file('tasks/sprockets.rake', after: /require 'sprockets'\n/) do
45
+ " require 'bootstrap'\n"
46
+ end
47
+ end
48
+
49
+ def remove_normalize_css
50
+ return unless sprockets?
51
+
52
+ gsub_file(
53
+ 'views/layout.erb',
54
+ '<link rel="stylesheet" type="text/css" ' \
55
+ 'href="//cdnjs.cloudflare.com/ajax/libs/normalize/2.1.3/normalize.min.css">',
56
+ ''
57
+ )
58
+ end
59
+
60
+ def reminders
61
+ if sprockets?
62
+ say "\nGemfile updated... don't forget to 'bundle install'"
63
+ else
64
+ text = <<~TEXT
65
+ Sprockets is required. Please install the Sprockets add-on
66
+ first (hoboken add:sprockets).
67
+ TEXT
68
+
69
+ say text, :red
70
+ end
71
+ end
72
+
73
+ private
74
+
75
+ def sprockets?
76
+ Dir.exist?('assets')
77
+ end
78
+ end
79
+ end
80
+ end
@@ -1,6 +1,11 @@
1
- require "rbconfig"
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
 
@@ -10,90 +15,152 @@ module Hoboken
10
15
 
11
16
  class_option :ruby_version,
12
17
  type: :string,
13
- desc: "Ruby version for Gemfile",
18
+ desc: 'Ruby version for Gemfile',
14
19
  default: RUBY_VERSION
15
20
 
16
21
  class_option :tiny,
17
22
  type: :boolean,
18
- desc: "Generate views inline; do not create /public folder",
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: "Architecture type (classic or modular)",
28
+ desc: 'Architecture type (classic or modular)',
24
29
  default: :classic
25
30
 
26
31
  class_option :git,
27
32
  type: :boolean,
28
- desc: "Create a Git repository and make initial commit",
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("classic.rb.tt", "app.rb")
38
- apply_template("Gemfile.erb.tt", "Gemfile")
39
- apply_template("config.ru.tt", "config.ru")
40
- apply_template("README.md.tt", "README.md")
41
- apply_template("Rakefile.tt", "Rakefile")
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
61
+ end
62
+
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}.sh", target)
68
+ chmod(target, 0o755)
69
+ end
70
+ end
71
+
72
+ def config_folder
73
+ empty_directory("#{snake_name}/config")
74
+ apply_template('puma.rb.tt', 'config/puma.rb')
42
75
  end
43
76
 
44
77
  def view_folder
78
+ return if options[:api_only]
79
+
45
80
  empty_directory("#{snake_name}/views")
46
- apply_template("views/layout.erb.tt", "views/layout.erb")
47
- apply_template("views/index.erb.tt", "views/index.erb")
81
+ apply_template('views/layout.erb.tt', 'views/layout.erb')
82
+ apply_template('views/index.erb.tt', 'views/index.erb')
48
83
  end
49
84
 
50
85
  def public_folder
51
- return if options[:tiny]
86
+ return if options[:tiny] || options[:api_only]
87
+
52
88
  inside snake_name do
53
- empty_directory("public")
54
- %w(css img js).each { |f| empty_directory("public/#{f}") }
89
+ empty_directory('public')
90
+ %w[css img js].each { |f| empty_directory("public/#{f}") }
55
91
  end
56
- apply_template("styles.css.tt", "public/css/styles.css")
57
- create_file("#{snake_name}/public/js/app.js", "")
58
92
 
59
- %w(favicon hoboken sinatra).each do |f|
93
+ apply_template('styles.css.tt', 'public/css/styles.css')
94
+ create_file("#{snake_name}/public/js/app.js", '')
95
+
96
+ %w[favicon hoboken sinatra].each do |f|
60
97
  copy_file("templates/#{f}.png", "#{snake_name}/public/img/#{f}.png")
61
98
  end
62
99
  end
63
100
 
64
101
  def test_folder
102
+ return unless 'test-unit' == options[:test_framework]
103
+
65
104
  empty_directory("#{snake_name}/test/unit")
66
105
  empty_directory("#{snake_name}/test/integration")
67
106
  empty_directory("#{snake_name}/test/support")
68
- apply_template("test/test_helper.rb.tt", "test/test_helper.rb")
69
- apply_template("test/unit/app_test.rb.tt", "test/unit/app_test.rb")
70
- apply_template("test/support/rack_test_assertions.rb.tt", "test/support/rack_test_assertions.rb")
107
+ apply_template('test_unit.rake.tt', 'tasks/test_unit.rake')
108
+ apply_template('test/test_helper.rb.tt', 'test/test_helper.rb')
109
+ apply_template('test/unit/app_test.rb.tt', 'test/unit/app_test.rb')
110
+ apply_template('support/rack_helpers.rb.tt', 'test/support/rack_helpers.rb')
111
+ apply_template('support/rack_test_assertions.rb.tt',
112
+ 'test/support/rack_test_assertions.rb')
113
+ end
114
+
115
+ def rspec_setup
116
+ return unless 'rspec' == options[:test_framework]
117
+
118
+ empty_directory("#{snake_name}/spec")
119
+ empty_directory("#{snake_name}/spec/support")
120
+ create_file("#{snake_name}/.rspec") { '--require spec_helper' }
121
+ apply_template('rspec.rake.tt', 'tasks/rspec.rake')
122
+ apply_template('spec/app_spec.rb.tt', 'spec/app_spec.rb')
123
+ apply_template('spec/spec_helper.rb.tt', 'spec/spec_helper.rb')
124
+ apply_template('support/rack_helpers.rb.tt', 'spec/support/rack_helpers.rb')
125
+ apply_template('spec/rack_matchers.rb.tt', 'spec/support/rack_matchers.rb')
71
126
  end
72
127
 
73
128
  def env_file
74
129
  inside snake_name do
75
- create_file(".env") do
130
+ create_file('.env') do
76
131
  "RACK_ENV=development\nPORT=9292"
77
132
  end
78
133
  end
79
134
  end
80
135
 
136
+ # rubocop:disable Metrics/AbcSize
81
137
  def make_modular
82
- return unless "modular" == options[:type]
138
+ return unless 'modular' == options[:type]
139
+
83
140
  empty_directory("#{snake_name}/helpers")
84
141
  remove_file("#{snake_name}/app.rb")
85
- apply_template("modular.rb.tt", "app.rb")
86
- ["config.ru", "test/test_helper.rb"].each do |f|
142
+ apply_template('modular.rb.tt', 'app.rb')
143
+
144
+ files = [].tap do |f|
145
+ f << 'config.ru'
146
+ f << 'test/support/rack_helpers.rb' if 'test-unit' == options[:test_framework]
147
+ f << 'spec/support/rack_helpers.rb' if 'rspec' == options[:test_framework]
148
+ end
149
+
150
+ files.each do |f|
87
151
  path = File.join(snake_name, f)
88
152
  gsub_file(path, /Sinatra::Application/, "#{camel_name}::App")
89
153
  end
90
154
  end
155
+ # rubocop:enable Metrics/AbcSize
91
156
 
92
157
  def inline_views
93
158
  return unless options[:tiny]
94
- combined_views = %w(layout index).map do |f|
159
+ return if options[:api_only]
160
+
161
+ combined_views = %w[layout index].map { |f|
95
162
  "@@#{f}\n" + File.read("#{snake_name}/views/#{f}.erb")
96
- end.join("\n")
163
+ }.join("\n")
97
164
 
98
165
  append_to_file("#{snake_name}/app.rb", "\n__END__\n\n#{combined_views}")
99
166
  remove_dir("#{snake_name}/views")
@@ -101,20 +168,26 @@ module Hoboken
101
168
 
102
169
  def create_git_repository
103
170
  return unless options[:git]
104
- if has_git?
105
- copy_file("templates/gitignore", "#{snake_name}/.gitignore")
171
+
172
+ if git?
173
+ copy_file('templates/gitignore', "#{snake_name}/.gitignore")
106
174
  inside snake_name do
107
- run("git init .")
108
- run("git add .")
109
- run("git commit -m \"Initial commit.\"")
175
+ run('git init .')
176
+ run('git add .')
177
+ run('git commit -m "Initial commit."')
110
178
  end
111
179
  else
112
- say "\nYou asked that a Git repository be created for the project, but no Git executable could be found."
180
+ say "\nYou asked that a Git repository be created for the " \
181
+ 'project, but no Git executable could be found.'
113
182
  end
114
183
  end
115
184
 
116
185
  def directions
117
- say "\nSuccessfully created #{name}. Don't forget to `bundle install`"
186
+ say "\nSuccessfully created #{name}."
187
+ end
188
+
189
+ def self.exit_on_failure?
190
+ true
118
191
  end
119
192
 
120
193
  private
@@ -124,15 +197,15 @@ module Hoboken
124
197
  end
125
198
 
126
199
  def camel_name
127
- Thor::Util.camel_case(name.split("/").last)
200
+ Thor::Util.camel_case(name.split('/').last)
128
201
  end
129
202
 
130
203
  def titleized_name
131
- snake_name.split("_").map(&:capitalize).join(" ")
204
+ snake_name.split('_').map(&:capitalize).join(' ')
132
205
  end
133
206
 
134
207
  def author
135
- if has_git?
208
+ if git?
136
209
  `git config user.name`.chomp
137
210
  else
138
211
  say "\nNo Git executable found. Using result of `whoami` as author name."
@@ -140,7 +213,7 @@ module Hoboken
140
213
  end
141
214
  end
142
215
 
143
- def has_git?
216
+ def git?
144
217
  system("git --version >#{NULL} 2>&1")
145
218
  end
146
219
 
@@ -148,4 +221,5 @@ module Hoboken
148
221
  template("templates/#{src}", "#{snake_name}/#{dest}")
149
222
  end
150
223
  end
224
+ # rubocop:enable Metrics/ClassLength
151
225
  end