hoboken 0.0.1 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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,17 +1,40 @@
1
- source "https://rubygems.org"
2
- ruby "<%= options[:ruby_version] %>"
1
+ # frozen_string_literal: true
3
2
 
4
- gem "rack_csrf", "~> 2.4.0"
5
- gem "sinatra", "~> 1.4.3"
6
- gem "thin", "~> 1.5.1"
3
+ source 'https://rubygems.org'
4
+ ruby '<%= options[:ruby_version] %>'
5
+
6
+ <% unless options[:api_only] -%>
7
+ gem 'erubi', '~> 1.10'
8
+ <% end -%>
9
+ gem 'puma', '~> 5.2'
10
+ gem 'rack_csrf', '~> 2.6'
11
+ gem 'sinatra', '~> 2.1'
12
+ gem 'sinatra-contrib', '~> 2.1'
13
+ <% unless options[:api_only] -%>
14
+ gem 'sinatra-flash', '~> 0.3'
15
+ <% end -%>
7
16
 
8
17
  group :development do
9
- gem "rake", "~> 10.1.0"
10
- gem "sinatra-reloader", "~> 1.0"
18
+ gem 'better_errors', '~> 2.9'
19
+ gem 'binding_of_caller', '~> 1.0'
20
+ gem 'dotenv', '~> 2.7'
21
+ gem 'pry-byebug', '~> 3.9'
22
+ gem 'racksh', '~> 1.0'
23
+ gem 'rake', '~> 13.0'
24
+ gem 'rerun', '~> 0.13'
25
+ gem 'rb-fsevent', '~> 0.10'
11
26
  end
12
27
 
13
28
  group :test do
14
- gem "contest", "~> 0.1.3"
29
+ <% if 'test-unit' == options[:test_framework] -%>
30
+ gem 'contest', '~> 0.1'
31
+ <% end -%>
32
+ gem 'rack-test', '~> 1.1'
33
+ <% if 'rspec' == options[:test_framework] -%>
34
+ gem 'rspec', '~> 3.10'
35
+ <% end -%>
36
+ <% if 'test-unit' == options[:test_framework] -%>
37
+ gem 'test-unit', '~> 3.4'
38
+ <% end -%>
39
+ gem 'warning', '~> 1.2'
15
40
  end
16
-
17
- gem "dotenv", "~> 0.9.0", group: :development
@@ -1,50 +1,120 @@
1
1
  # <%= titleized_name %>
2
2
 
3
+ ## Overview
4
+
3
5
  TODO: Project description.
4
6
 
7
+ * TODO: a list of
8
+ * high level features
9
+ * ...
10
+
11
+ ### Links
12
+ * [Production](TODO)
13
+ * [QA](TODO)
14
+ * [Issue Tracking](TODO)
15
+ * [Continuous Integration](TODO)
16
+
17
+ ### Table of Contents
18
+
19
+ * [Overview](#overview)
20
+ * [Getting Started](#getting-started)
21
+ * [Configuration](#configuration)
22
+ <% if 'rspec' == options[:test_framework] -%>
23
+ * [Specs](#specs)
24
+ <% else -%>
25
+ * [Tests](#tests)
26
+ <% end -%>
27
+ * [Rake Tasks](#rake-tasks)
28
+ * [Logging](#logging)
29
+ * [Deploying](#deploying)
30
+ * [Dev Notes](#dev-notes)
31
+
5
32
  ## Getting Started
6
33
 
7
- ### Starting the Server
34
+ The following pre-requisites are needed to build this project:
35
+ * Ruby <%= RUBY_VERSION %>
36
+ * [Bundler](https://bundler.io/)
8
37
 
9
- ### Project Layout
38
+ After cloning this repository, the project can be setup by running the `./bin/setup` script. This script will install dependencies and perform any other required setup tasks.
10
39
 
11
- ## Notes / Use
40
+ Once setup is complete, you can start a local development server by running the `./bin/server` script. Additionally, you can start a development console using the `./bin/console` script. The console uses the [racksh](https://github.com/sickill/racksh) gem which exposes a `$rack` variable that can be used to make simulated HTTP requests.
12
41
 
13
- ## Contributing
42
+ ## Configuration
43
+ Environment variables are used for project configuration. For local development, the `.env` file is used. Below is a sample `.env` file that contains the minimum required configuration.
14
44
 
15
- ### Issues / Roadmap
45
+ ```
46
+ RACK_ENV=development
47
+ ```
16
48
 
17
- Use GitHub issues for reporting bug and feature requests.
49
+ Here is a table containing all available environment variable configuration options and their descriptions.
18
50
 
19
- ### Patches / Pull Requests
20
- * Fork the project.
21
- * Make your feature addition or bug fix.
22
- * Add tests for it. This is important so I don’t break it in a future version
23
- unintentionally.
24
- * Commit, do not mess with Rakefile, version, or history (if you want to have
25
- your own version, that is fine but bump version in a commit by itself I can
26
- ignore when I pull).
27
- * Send me a pull request. Bonus points for topic branches.
51
+ <table>
52
+ <thead>
53
+ <tr>
54
+ <th>Name</th>
55
+ <th>Required?</th>
56
+ <th>Default Value</th>
57
+ <th>Description</th>
58
+ </tr>
59
+ </thead>
60
+ <tbody>
61
+ <tr>
62
+ <td>MAX_THREADS</td>
63
+ <td>No</td>
64
+ <td>5</td>
65
+ <td>The maximum number of threads that a Puma worker process should use</td>
66
+ </tr>
67
+ <tr>
68
+ <td>PORT</td>
69
+ <td>No</td>
70
+ <td>9292</td>
71
+ <td>Web server port</td>
72
+ </tr>
73
+ <tr>
74
+ <td>RACK_ENV</td>
75
+ <td>No</td>
76
+ <td>production</td>
77
+ <td>Web server environment (i.e. development, test, production, etc.)</td>
78
+ </tr>
79
+ <tr>
80
+ <td>WEB_CONCURRENCY</td>
81
+ <td>No</td>
82
+ <td>1</td>
83
+ <td>The number of Puma worker processes</td>
84
+ </tr>
85
+ </tbody>
86
+ </table>
28
87
 
29
- ## License
30
- (The MIT License)
88
+ ## Development
89
+ This project has the following default behavior:
31
90
 
32
- Copyright (c) <%= Date.today.year %> <%= author %>
91
+ * helpers scripts for common project actions; refer to the `bin` folder
92
+ * uses [Puma](https://github.com/puma/puma) as the default web server
93
+ * [erubi](https://github.com/jeremyevans/erubi) for templating; escaping is done by default
94
+ * [Rack::Csrf](http://rubygems.org/gems/rack_csrf") is turned on by default
95
+ * environment variable support via the [dotenv](http://rubygems.org/gems/dotenv) gem
96
+ * Procfile for [foreman](https://github.com/ddollar/foreman) support; if foreman is not installed uses rackup instead
97
+ * code reloading via the [rerun](https://github.com/alexch/rerun) gem is enabled for the development environment
98
+ * [pry-byebug](https://github.com/deivid-rodriguez/pry-byebug") is installed for debugging
33
99
 
34
- Permission is hereby granted, free of charge, to any person obtaining a copy
35
- of this software and associated documentation files (the "Software"), to deal
36
- in the Software without restriction, including without limitation the rights
37
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
38
- copies of the Software, and to permit persons to whom the Software is
39
- furnished to do so, subject to the following conditions:
40
-
41
- The above copyright notice and this permission notice shall be included in
42
- all copies or substantial portions of the Software.
43
-
44
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
45
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
46
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
47
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
48
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
49
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
50
- SOFTWARE.
100
+ <% if 'rspec' == options[:test_framework] -%>
101
+ ## Specs
102
+ This project uses [RSpec](https://rspec.info/) for testing. Specs can be ran using the rake task `rake spec`.
103
+ <% else -%>
104
+ ## Tests
105
+ This project uses [Test Unit](https://test-unit.github.io/) for testing. Tests can be ran using the rake task `rake test:all`.
106
+ <% end -%>
107
+
108
+ ## Rake Tasks
109
+ To see a list of available tasks run the `rake -T` command.
110
+
111
+ ## Logging
112
+ TODO: Describe how logging is setup (i.e. files, STDOUT, services like Papertrail, DataDog, etc.).
113
+
114
+ ## Deploying
115
+ TODO: Describe how to deploy the project (QA, production, CI setup, etc.). Don't forget to describe how project environment variables are set for the various deployment targets.
116
+
117
+ ## Dev Notes
118
+
119
+ ## License
120
+ Copyright (c) <%= Date.today.year %> <%= author %>
@@ -1,28 +1,16 @@
1
- require "rake/testtask"
2
-
3
- task :default => "test:all"
1
+ # frozen_string_literal: true
4
2
 
5
3
  # Import any external rake tasks
6
4
  Dir.glob('tasks/*.rake').each { |r| import r }
7
5
 
8
- desc "Start the development server"
9
- task :server do
10
- port = ENV["PORT"] || 9292
11
- rack_env = ENV["RACK_ENV"] || "development"
12
- exec("bundle exec thin start -p #{port} -e #{rack_env}")
13
- end
14
-
15
- namespace :test do
16
- Rake::TestTask.new(:unit) do |t|
17
- t.libs << 'test/unit'
18
- t.test_files = Dir["test/unit/**/*_test.rb"]
19
- end
6
+ <% if 'test-unit' == options[:test_framework] -%>
7
+ task default: 'test:all'
20
8
 
21
- Rake::TestTask.new(:integration) do |t|
22
- t.libs << 'test/unit'
23
- t.test_files = Dir["test/integration/**/*_test.rb"]
24
- end
9
+ desc 'Run CI checks'
10
+ task ci: ['test:all']
11
+ <% else -%>
12
+ task default: 'spec'
25
13
 
26
- desc "Run all tests"
27
- task :all => %w[test:unit test:integration]
28
- end
14
+ desc 'Run CI checks'
15
+ task ci: ['spec']
16
+ <% end -%>
@@ -1,16 +1,43 @@
1
- require "bundler/setup"
2
- require "sinatra"
3
- require "rack/csrf"
1
+ # frozen_string_literal: true
4
2
 
5
- Dir.glob(File.join("helpers", "**", "*.rb")).each do |helper|
3
+ require 'bundler/setup'
4
+
5
+ <% unless options[:api_only] -%>
6
+ require 'erubi'
7
+ <% end -%>
8
+ require 'rack/csrf'
9
+ require 'sinatra'
10
+ <% if options[:api_only] -%>
11
+ require 'sinatra/json'
12
+ <% else -%>
13
+ require 'sinatra/flash'
14
+ <% end -%>
15
+
16
+ Dir.glob(File.join('helpers', '**', '*.rb')).each do |helper|
6
17
  require_relative helper
7
18
  end
8
19
 
9
- require "sinatra/reloader" if development?
20
+ configure do
21
+ use Rack::Session::Cookie, secret: 'TODO: CHANGE ME'
22
+ use Rack::Csrf, raise: true
23
+ <% unless options[:api_only] -%>
24
+
25
+ set :erb, { escape_html: true }
26
+ <% end -%>
27
+ end
10
28
 
11
- use Rack::Session::Cookie, :secret => "TODO: CHANGE ME"
12
- use Rack::Csrf, :raise => true
29
+ configure :development do
30
+ require 'better_errors'
31
+ use BetterErrors::Middleware
32
+ BetterErrors.application_root = __dir__
33
+ end
13
34
 
14
- get "/" do
35
+ <% if options[:api_only] -%>
36
+ get '/' do
37
+ json message: 'Smoke test successful!'
38
+ end
39
+ <% else -%>
40
+ get '/' do
15
41
  erb :index
16
42
  end
43
+ <% end -%>
@@ -1,5 +1,7 @@
1
- require "bundler/setup"
2
- require "dotenv"
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/setup'
4
+ require 'dotenv'
3
5
  Dotenv.load
4
- require File.expand_path("../app", __FILE__)
6
+ require File.expand_path('app', __dir__)
5
7
  run Sinatra::Application
@@ -0,0 +1,5 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle exec racksh
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ if ENV['DATABASE_URL']
4
+ require 'logger'
5
+ require 'sequel'
6
+
7
+ args = 'test' == ENV['RACK_ENV'] ? ['tmp/db_test.log', 'daily'] : [$stdout]
8
+ DB = Sequel.connect(ENV['DATABASE_URL'], loggers: [Logger.new(*args)])
9
+ Sequel.extension :migration
10
+
11
+ unless Dir.glob('db/migrate/*.rb').empty?
12
+ begin
13
+ Sequel::Migrator.check_current(DB, 'db/migrate')
14
+ rescue Sequel::Migrator::NotCurrentError
15
+ puts 'Pending migrations detected... running migrations'
16
+ Sequel::Migrator.run(DB, 'db/migrate')
17
+ puts 'Database migrations completed'
18
+ end
19
+ end
20
+ DB.freeze unless 'development' == ENV['RACK_ENV']
21
+ puts 'Database connected'
22
+ else
23
+ puts 'DATABASE_URL not set; skipping database initialization'
24
+ end
@@ -0,0 +1,28 @@
1
+ # This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
2
+ # For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
3
+
4
+ name: Ruby
5
+
6
+ on:
7
+ push:
8
+ pull_request:
9
+ schedule:
10
+ - cron: "0 4 * * *"
11
+
12
+ jobs:
13
+ test:
14
+
15
+ runs-on: ubuntu-latest
16
+ strategy:
17
+ matrix:
18
+ ruby-version: [<%= RUBY_VERSION %>]
19
+
20
+ steps:
21
+ - uses: actions/checkout@v2
22
+ - name: Set up Ruby
23
+ uses: ruby/setup-ruby@v1
24
+ with:
25
+ ruby-version: ${{ matrix.ruby-version }}
26
+ bundler-cache: true
27
+ - name: Run tests
28
+ run: bundle exec rake ci
@@ -1,5 +1,12 @@
1
1
  .DS_Store
2
2
  .bundle
3
+ .byebug_history
4
+ .env
5
+ .env.test
6
+ .rspec_status
3
7
  /tmp
8
+ coverage
9
+ db/*.db
10
+ public
11
+ spec/examples.txt
4
12
  tags
5
- .env
@@ -1,9 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  unless 'production' == ENV['RACK_ENV']
2
4
  require 'flay'
3
- desc "Analyze code for structural similarities"
5
+ desc 'Analyze code for structural similarities'
4
6
  task :flay do
5
7
  flay = Flay.new
6
- files = FileList["app.rb", "app/**/*.rb"]
8
+ files = FileList['app.rb', 'app/**/*.rb']
7
9
  flay.process(*files)
8
10
  threshold = 200
9
11
 
@@ -13,21 +15,20 @@ unless 'production' == ENV['RACK_ENV']
13
15
  end
14
16
  end
15
17
 
16
- require "flog"
18
+ require 'flog'
17
19
  desc 'Analyze code complexity'
18
20
  task :flog do
19
21
  flog = Flog.new
20
- flog.flog FileList["app.rb", "app/**/*.rb"]
22
+ files = FileList['app.rb', 'app/**/*.rb']
23
+ flog.flog(*files)
21
24
  threshold = 50
22
25
 
23
- bad_methods = flog.totals.select do |name, score|
26
+ bad_methods = flog.totals.select do |_name, score|
24
27
  score > threshold
25
28
  end
26
29
 
27
- bad_methods.sort do |a, b|
28
- a[1] <=> b[1]
29
- end.each do |name, score|
30
- puts "%8.1f: %s" % [score, name]
30
+ bad_methods.sort { |a, b| a[1] <=> b[1] }.each do |name, score|
31
+ puts format('%<score>8.1f: %<name>s', score: score, name: name)
31
32
  end
32
33
 
33
34
  unless bad_methods.empty?
@@ -1,27 +1,56 @@
1
- require "bundler/setup"
2
- require "sinatra/base"
3
- require "rack/csrf"
1
+ # frozen_string_literal: true
4
2
 
5
- Dir.glob(File.join("helpers", "**", "*.rb")).each do |helper|
3
+ require 'bundler/setup'
4
+
5
+ <% unless options[:api_only] -%>
6
+ require 'erubi'
7
+ <% end -%>
8
+ require 'rack/csrf'
9
+ require 'sinatra/base'
10
+ <% if options[:api_only] -%>
11
+ require 'sinatra/json'
12
+ <% else -%>
13
+ require 'sinatra/flash'
14
+ <% end -%>
15
+
16
+ Dir.glob(File.join('helpers', '**', '*.rb')).each do |helper|
6
17
  require_relative helper
7
18
  end
8
19
 
9
20
  module <%= camel_name %>
21
+ # Sinatra web application
22
+ #
10
23
  class App < Sinatra::Base
11
- set :root, File.dirname(__FILE__)
24
+ configure do
25
+ set :root, File.dirname(__FILE__)
26
+ <% unless options[:api_only] -%>
27
+ set :erb, { escape_html: true }
28
+ <% end -%>
12
29
 
13
- enable :logging
30
+ enable :logging
14
31
 
15
- use Rack::Session::Cookie, :secret => "TODO: CHANGE ME"
16
- use Rack::Csrf, :raise => true
32
+ use Rack::Session::Cookie, secret: 'TODO: CHANGE ME'
33
+ use Rack::Csrf, raise: true
34
+ <% unless options[:api_only] -%>
35
+
36
+ register Sinatra::Flash
37
+ <% end -%>
38
+ end
17
39
 
18
40
  configure :development do
19
- require "sinatra/reloader"
20
- register Sinatra::Reloader
41
+ require 'better_errors'
42
+ use BetterErrors::Middleware
43
+ BetterErrors.application_root = __dir__
21
44
  end
22
45
 
23
- get "/" do
46
+ <% if options[:api_only] -%>
47
+ get '/' do
48
+ json message: 'Smoke test successful!'
49
+ end
50
+ <% else -%>
51
+ get '/' do
24
52
  erb :index
25
53
  end
54
+ <% end -%>
26
55
  end
27
56
  end