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,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