grape-starter 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +12 -0
  3. data/.rubocop.yml +36 -0
  4. data/.rubocop_todo.yml +12 -0
  5. data/.travis.yml +5 -0
  6. data/CHANGELOG.md +27 -0
  7. data/Gemfile +4 -0
  8. data/LICENSE +21 -0
  9. data/README.md +70 -0
  10. data/Rakefile +14 -0
  11. data/bin/grape-starter +119 -0
  12. data/grape-starter.gemspec +36 -0
  13. data/lib/starter.rb +9 -0
  14. data/lib/starter/builder.rb +90 -0
  15. data/lib/starter/builder/names.rb +56 -0
  16. data/lib/starter/builder/template_endpoints.rb +97 -0
  17. data/lib/starter/builder/template_files.rb +73 -0
  18. data/lib/starter/rake/grape_tasks.rb +71 -0
  19. data/lib/starter/rspec/request_specs.rb +109 -0
  20. data/lib/starter/version.rb +4 -0
  21. data/template/.rubocop.yml +15 -0
  22. data/template/.rubocop_todo.yml +28 -0
  23. data/template/Gemfile +23 -0
  24. data/template/LICENSE +21 -0
  25. data/template/README.md +70 -0
  26. data/template/Rakefile +25 -0
  27. data/template/api/base.rb +18 -0
  28. data/template/api/endpoints/root.rb +20 -0
  29. data/template/api/entities/api_error.rb +17 -0
  30. data/template/api/entities/route.rb +22 -0
  31. data/template/config.ru +12 -0
  32. data/template/config/application.rb +22 -0
  33. data/template/config/boot.rb +3 -0
  34. data/template/config/environment.rb +4 -0
  35. data/template/lib/api.rb +6 -0
  36. data/template/lib/api/version.rb +4 -0
  37. data/template/script/console +8 -0
  38. data/template/script/server +14 -0
  39. data/template/script/setup +6 -0
  40. data/template/script/stop +8 -0
  41. data/template/script/test +17 -0
  42. data/template/script/update +6 -0
  43. data/template/spec/lib/api/version_spec.rb +8 -0
  44. data/template/spec/requests/documentation_spec.rb +12 -0
  45. data/template/spec/requests/root_spec.rb +25 -0
  46. data/template/spec/spec_helper.rb +25 -0
  47. metadata +216 -0
data/template/Gemfile ADDED
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+ source 'http://rubygems.org'
3
+
4
+ gem 'thin'
5
+
6
+ gem 'rack'
7
+ gem 'rack-cors'
8
+
9
+ # TODO: revert to gem after mörge and release
10
+ gem 'grape', git: 'git@github.com:LeFnord/grape.git', branch: 'delete_204'
11
+ # gem 'grape', '~> 0.18'
12
+ gem 'grape-entity', '~> 0.6'
13
+ gem 'grape-swagger', '~> 0.25'
14
+ gem 'grape-swagger-entity', '~> 0.1.5'
15
+
16
+ group :development, :test do
17
+ gem 'grape-starter'
18
+ gem 'pry'
19
+ gem 'rack-test'
20
+ gem 'rake'
21
+ gem 'rspec'
22
+ gem 'rubocop'
23
+ end
data/template/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Peter Scholz
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,70 @@
1
+ # adept it to your needs
2
+
3
+ # Grape API on Rack
4
+
5
+ A [Grape](http://github.com/ruby-grape/grape) API mounted on [Rack](https://github.com/rack/rack), starting point for API development with Grape. It also includes [grape-swagger](http://github.com/ruby-grape/grape-swagger) for documentation generating.
6
+
7
+
8
+ ## Usage
9
+
10
+ #### Setup
11
+
12
+ ```
13
+ $ git clone git@github.com:LeFnord/grape-starter.git
14
+ $ cd grape-starter
15
+ $ ./script/setup
16
+ ```
17
+
18
+ #### Test
19
+
20
+ ```
21
+ $ ./script/test
22
+ ```
23
+
24
+ #### Run
25
+
26
+ ```
27
+ $ ./script/server
28
+ ```
29
+
30
+ or for production, set `RACK_ENV=production`
31
+ ```
32
+ $ export RACK_ENV=production ./script/server
33
+ ```
34
+
35
+ #### Update
36
+
37
+ … dependencies
38
+ ```
39
+ $ ./script/update
40
+ ```
41
+
42
+ #### Stop
43
+
44
+ … would only be used, if server started in production mode
45
+ ```
46
+ $ ./script/stop
47
+ ```
48
+
49
+
50
+ ## Rake Tasks
51
+
52
+ #### List Routes
53
+
54
+ ```
55
+ rake grape:routes
56
+ ```
57
+
58
+ #### OpenApi Documentation and Validation
59
+
60
+ -> see [`grape-swagger` Rake Tasks](https://github.com/ruby-grape/grape-swagger#rake-tasks)
61
+
62
+
63
+ ## Contributing
64
+
65
+ Bug reports and pull requests are welcome on GitHub at https://github.com/name/repo.
66
+
67
+
68
+ ## License
69
+
70
+ The gem is available as open source under the terms of the [MIT License](LICENSE).
data/template/Rakefile ADDED
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+ require 'rake'
3
+
4
+ require 'rspec/core'
5
+ require 'rspec/core/rake_task'
6
+
7
+ RSpec::Core::RakeTask.new(:spec)
8
+
9
+ task :environment do
10
+ ENV['RACK_ENV'] ||= 'development'
11
+ require File.expand_path('../config/environment', __FILE__)
12
+ end
13
+
14
+ require 'rubocop/rake_task'
15
+ RuboCop::RakeTask.new(:rubocop)
16
+
17
+ task default: [:rubocop, :spec]
18
+
19
+ require File.expand_path('../config/environment', __FILE__)
20
+
21
+ require 'grape-swagger/rake/oapi_tasks'
22
+ GrapeSwagger::Rake::OapiTasks.new(::Api::Base)
23
+
24
+ require 'starter/rake/grape_tasks'
25
+ Starter::Rake::GrapeTasks.new(::Api::Base)
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+ module Api
3
+ class Base < Grape::API
4
+ prefix :api
5
+ version 'v1', using: :path
6
+ format :json
7
+
8
+ mount Endpoints::Root
9
+
10
+ add_swagger_documentation format: :json,
11
+ info: {
12
+ title: 'Starter API'
13
+ },
14
+ models: [
15
+ Entities::ApiError
16
+ ]
17
+ end
18
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+ require 'starter/rake/grape_tasks'
3
+
4
+ module Api
5
+ module Endpoints
6
+ class Root < Grape::API
7
+ namespace :root do
8
+ desc 'Exposes all routes',
9
+ success: Entities::Route,
10
+ is_array: true
11
+ get do
12
+ api_routes = Starter::Rake::GrapeTasks.new(::Api::Base).api_routes
13
+
14
+ present :count, api_routes.length
15
+ present :items, api_routes, with: Entities::Route
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+ module Api
3
+ module Entities
4
+ class ApiError < Grape::Entity
5
+ expose :code,
6
+ documentation: {
7
+ type: Integer,
8
+ desc: 'the http status code'
9
+ }
10
+ expose :message,
11
+ documentation: {
12
+ type: String,
13
+ desc: 'the error message'
14
+ }
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+ module Api
3
+ module Entities
4
+ class Route < Grape::Entity
5
+ expose :verb,
6
+ documentation: {
7
+ type: String,
8
+ desc: 'the http method of the route'
9
+ }
10
+ expose :path,
11
+ documentation: {
12
+ type: String,
13
+ desc: 'the route itself'
14
+ }
15
+ expose :description,
16
+ documentation: {
17
+ type: String,
18
+ desc: 'the route description'
19
+ }
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+ require 'rack/cors'
3
+ use Rack::Cors do
4
+ allow do
5
+ origins '*'
6
+ resource '*', headers: :any, methods: [:get, :post, :put, :delete, :options]
7
+ end
8
+ end
9
+
10
+ require File.expand_path('../config/application', __FILE__)
11
+
12
+ run Api::Base
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'api'))
4
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
5
+
6
+ require 'boot'
7
+
8
+ Bundler.require :default, ENV['RACK_ENV']
9
+
10
+ Dir[File.expand_path('../../lib/**/*.rb', __FILE__)].each do |lib|
11
+ require lib
12
+ end
13
+
14
+ Dir[File.expand_path('../../api/entities/*.rb', __FILE__)].each do |entity|
15
+ require entity
16
+ end
17
+
18
+ Dir[File.expand_path('../../api/endpoints/*.rb', __FILE__)].each do |endpoint|
19
+ require endpoint
20
+ end
21
+
22
+ require 'base'
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+ require 'rubygems'
3
+ require 'bundler/setup'
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+ ENV['RACK_ENV'] ||= 'test'
3
+
4
+ require File.expand_path('../application', __FILE__)
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+ require 'api/version'
3
+
4
+ module Api
5
+ APP_CLASS = name
6
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+ module Api
3
+ VERSION = '0.1.0'
4
+ end
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+
4
+ require 'bundler/setup'
5
+ require 'api'
6
+
7
+ require 'pry'
8
+ Pry.start
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env bash
2
+
3
+ set -e
4
+
5
+ cd "$(dirname "$0")/.."
6
+
7
+ test -z "$RACK_ENV" &&
8
+ RACK_ENV='development'
9
+
10
+ if [ "$RACK_ENV" = 'production' ]; then
11
+ bundle exec thin start -p 9292 -e $RACK_ENV --tag api-starter -d --threaded
12
+ else
13
+ bundle exec thin start -p 9292 -e $RACK_ENV --tag api-starter -V -D
14
+ fi
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+
3
+ set -e
4
+
5
+ cd "$(dirname "$0")/.."
6
+
7
+ # use only, if server was started in production mode
8
+ thin stop
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env sh
2
+
3
+ set -e
4
+
5
+ cd "$(dirname "$0")/.."
6
+
7
+ [ -z "$DEBUG" ] || set -x
8
+
9
+ echo "===> Running rubocop..."
10
+ bundle exec rake rubocop
11
+
12
+ echo "===> Running specs..."
13
+ if [ $1 ]; then
14
+ bundle exec rspec $1
15
+ else
16
+ bundle exec rspec
17
+ fi
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle update
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+ require 'spec_helper'
3
+
4
+ describe Api do
5
+ it 'has a version number' do
6
+ expect(Api::VERSION).not_to be nil
7
+ end
8
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+ require 'spec_helper'
3
+
4
+ RSpec.describe Api::Base do
5
+ subject(:swagger) do
6
+ get '/api/v1/swagger_doc'
7
+ last_response
8
+ end
9
+
10
+ specify { expect(swagger.status).to eql 200 }
11
+ specify { expect(swagger.body).not_to be_empty }
12
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+ require 'spec_helper'
3
+
4
+ RSpec.describe Api::Base do
5
+ let(:exposed_keys) do
6
+ [
7
+ :verb,
8
+ :path,
9
+ :description
10
+ ]
11
+ end
12
+
13
+ subject { get '/api/v1/root' }
14
+ specify { expect(subject.status).to eql 200 }
15
+
16
+ let(:response) { JSON.parse(subject.body, symbolize_names: true) }
17
+ specify { expect(response.keys).to include :count, :items }
18
+
19
+ let(:items) { response[:items] }
20
+ specify 'has items with values' do
21
+ items.each do |item|
22
+ expect(item.keys).to include(*exposed_keys)
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+ ENV['RACK_ENV'] ||= 'test'
3
+
4
+ require 'rack/test'
5
+ require File.expand_path('../../config/environment', __FILE__)
6
+
7
+ grape_starter_gem = Gem::Specification.find_by_name('grape-starter').gem_dir
8
+
9
+ Dir[grape_starter_gem + '/lib/starter/rspec/**/*.rb'].each { |f| require f }
10
+
11
+ RSpec.configure do |config|
12
+ config.color = true
13
+ config.formatter = :documentation
14
+
15
+ config.mock_with :rspec
16
+ config.expect_with :rspec
17
+
18
+ config.raise_errors_for_deprecations!
19
+ end
20
+
21
+ include Rack::Test::Methods
22
+
23
+ def app
24
+ Api::Base
25
+ end