grape-starter 0.7.0 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop_todo.yml +1 -1
- data/CHANGELOG.md +5 -0
- data/README.md +1 -1
- data/bin/grape-starter +1 -2
- data/lib/starter/builder.rb +16 -6
- data/lib/starter/builder/base_file.rb +3 -2
- data/lib/starter/builder/names.rb +4 -0
- data/lib/starter/builder/orms.rb +13 -2
- data/lib/starter/builder/templates/activerecord.rb +120 -0
- data/lib/starter/builder/templates/files.rb +2 -1
- data/lib/starter/config.rb +2 -1
- data/lib/starter/version.rb +1 -1
- data/template/api/base.rb +1 -3
- data/template/config.ru +1 -2
- data/template/config/application.rb +2 -1
- data/template/spec/requests/documentation_spec.rb +1 -1
- data/template/spec/requests/root_spec.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 45c1d0a951be87c5be14c08499f38ae04ccfbbdb
|
4
|
+
data.tar.gz: 4b9a797047eaf1271ab0d46a5eb7438043fbddcf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3c1d2224a49b34e3a9971c663dfd61acbb82f0f487d6e405ce7c83424d050c5227efe0307327e40599724c5f9264f2b5d8e1e0eec6fad535fe7adc1b87f6a473
|
7
|
+
data.tar.gz: bc11c7f804027886528c7c2872a68d224b6a02c5e335a582709d2260e34678d0715dfe8bdc287b09e5322cd759d9f311d2758949727a7cf62f536b156e72377c
|
data/.rubocop_todo.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,11 @@
|
|
2
2
|
|
3
3
|
- contributions
|
4
4
|
|
5
|
+
### 0.8.0
|
6
|
+
|
7
|
+
- [#15](https://github.com/LeFnord/grape-starter/pull/15), [2af09…](https://github.com/LeFnord/grape-starter/commit/2af09dddf97f756e96c80c745ee68aad5ab4ccc3) **breaking change** prefix option on create is optional, no default
|
8
|
+
- [#12](https://github.com/LeFnord/grape-starter/pull/12) - Add base configuration for ActiveRecord - ([@terry90](https://github.com/terry90))
|
9
|
+
|
5
10
|
### 0.7.0
|
6
11
|
|
7
12
|
- [212e6…](https://github.com/LeFnord/grape-starter/commit/212e6245e10598efe286143dac39f46134c58c54) - makes mounting of doc more secure
|
data/README.md
CHANGED
@@ -31,7 +31,7 @@ with following options:
|
|
31
31
|
```
|
32
32
|
-f, --force # overwrites existend project
|
33
33
|
-p foobar, --prefix=foobar # provide a prefix under which the API can be accessed, default: api
|
34
|
-
-o sequel, --orm=sequel # create
|
34
|
+
-o sequel, --orm=sequel # create files for the specified ORM, default: sequel, available: activerecord
|
35
35
|
```
|
36
36
|
|
37
37
|
This command creates a folder named `awesome_api` containing the skeleton. With following structure:
|
data/bin/grape-starter
CHANGED
@@ -23,11 +23,10 @@ desc 'Creates initial api skeleton'
|
|
23
23
|
arg_name 'awesome_api'
|
24
24
|
command :new do |c|
|
25
25
|
c.flag [:p, :prefix],
|
26
|
-
default_value: 'api',
|
27
26
|
desc: 'sets the prefix of the API'
|
28
27
|
c.flag [:o, :orm],
|
29
28
|
default_value: 'sequel',
|
30
|
-
desc: 'prepares for the given ORM (Sequel,
|
29
|
+
desc: 'prepares for the given ORM (Sequel -> sequel, ActiveRecord -> ar)'
|
31
30
|
|
32
31
|
c.action do |global_options, options, args|
|
33
32
|
dest = args.empty? ? nil : File.join(Dir.getwd, args.first)
|
data/lib/starter/builder.rb
CHANGED
@@ -28,21 +28,31 @@ module Starter
|
|
28
28
|
# source - A String which provides the template path
|
29
29
|
# destination - A String which provides the new project path
|
30
30
|
def new!(name, source, destination, options = {})
|
31
|
-
@prefix = options[:p] || 'api'
|
32
31
|
@resource = name
|
33
32
|
@destination = destination
|
33
|
+
@prefix = options[:p] # can be nil
|
34
34
|
|
35
35
|
FileUtils.copy_entry source, destination
|
36
36
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
replace_static(File.join('spec', 'requests', 'documentation_spec.rb'), prefix)
|
37
|
+
config_static.each do |config|
|
38
|
+
replace_static(File.join(config[:file]), config[:pattern])
|
39
|
+
end
|
41
40
|
|
42
41
|
Orms.build(destination, options[:orm]) if options[:orm]
|
42
|
+
Starter::Config.save(content: { prefix: prefix })
|
43
|
+
|
43
44
|
self
|
44
45
|
end
|
45
46
|
|
47
|
+
def config_static
|
48
|
+
[
|
49
|
+
{ file: %w[script server], pattern: "API-#{resource}" },
|
50
|
+
{ file: %w[api base.rb], pattern: prefix ? "prefix :#{prefix}" : nil },
|
51
|
+
{ file: %w[spec requests root_spec.rb], pattern: prefix ? "/#{prefix}" : nil },
|
52
|
+
{ file: %w[spec requests documentation_spec.rb], pattern: prefix ? "/#{prefix}" : nil }
|
53
|
+
]
|
54
|
+
end
|
55
|
+
|
46
56
|
# would be called from add command
|
47
57
|
#
|
48
58
|
# resource - A String as name
|
@@ -99,7 +109,7 @@ module Starter
|
|
99
109
|
def replace_static(file, replacement)
|
100
110
|
server_file = File.join(destination, file)
|
101
111
|
|
102
|
-
FileFoo.call!(server_file) { |content| content.gsub!('{{{grape-starter}}}', replacement) }
|
112
|
+
FileFoo.call!(server_file) { |content| content.gsub!('{{{grape-starter}}}', replacement.to_s) }
|
103
113
|
end
|
104
114
|
|
105
115
|
# #add! a new resource releated helper methods
|
@@ -27,8 +27,9 @@ module Starter
|
|
27
27
|
# parses out the prefix from base api file
|
28
28
|
def base_prefix
|
29
29
|
base_file
|
30
|
-
|
31
|
-
|
30
|
+
scan = base_file.scan(/prefix\s+(:.+)\n/)
|
31
|
+
scan.first.first.delete!(':') unless scan.empty?
|
32
|
+
# Starter::Config.read[:prefix]
|
32
33
|
end
|
33
34
|
|
34
35
|
# parses out the version from base api file
|
@@ -15,6 +15,10 @@ module Starter
|
|
15
15
|
require 'starter/builder/templates/sequel'
|
16
16
|
extend(::Starter::Templates::Sequel)
|
17
17
|
"#{klass_name} < #{model_klass}"
|
18
|
+
when 'activerecord', 'ar'
|
19
|
+
require 'starter/builder/templates/activerecord'
|
20
|
+
extend(::Starter::Templates::ActiveRecord)
|
21
|
+
"#{klass_name} < #{model_klass}"
|
18
22
|
else
|
19
23
|
klass_name
|
20
24
|
end
|
data/lib/starter/builder/orms.rb
CHANGED
@@ -4,10 +4,15 @@ module Starter
|
|
4
4
|
class Orms
|
5
5
|
class << self
|
6
6
|
def build(dest, orm)
|
7
|
-
case orm
|
7
|
+
case orm.downcase
|
8
8
|
when 'sequel'
|
9
9
|
require 'starter/builder/templates/sequel'
|
10
10
|
extend(::Starter::Templates::Sequel)
|
11
|
+
when 'activerecord', 'ar'
|
12
|
+
require 'starter/builder/templates/activerecord'
|
13
|
+
extend(::Starter::Templates::ActiveRecord)
|
14
|
+
# Fixes pooling
|
15
|
+
add_middleware(dest, 'ActiveRecord::Rack::ConnectionManagement')
|
11
16
|
else
|
12
17
|
return
|
13
18
|
end
|
@@ -17,7 +22,7 @@ module Starter
|
|
17
22
|
append_to_file(File.join(dest, 'Rakefile'), rakefile)
|
18
23
|
append_to_file(File.join(dest, 'Gemfile'), gemfile)
|
19
24
|
prepare_for_migrations(File.join(dest, 'db'))
|
20
|
-
Starter::Config.save(dest: dest, content: { orm: orm })
|
25
|
+
Starter::Config.save(dest: dest, content: { orm: orm.downcase })
|
21
26
|
end
|
22
27
|
|
23
28
|
private
|
@@ -31,6 +36,12 @@ module Starter
|
|
31
36
|
FileFoo.write_file(File.join(dest, 'database.yml'), config)
|
32
37
|
end
|
33
38
|
|
39
|
+
# adds a middleware to config.ru
|
40
|
+
def add_middleware(dest, middleware)
|
41
|
+
replacement = "use #{middleware}\n\n\\1"
|
42
|
+
FileFoo.call!(File.join(dest, 'config.ru')) { |content| content.sub!(/^(run.+)$/, replacement) }
|
43
|
+
end
|
44
|
+
|
34
45
|
def append_to_file(file_name, content)
|
35
46
|
original = FileFoo.read_file(file_name)
|
36
47
|
FileFoo.write_file(file_name, "#{original}\n\n#{content}")
|
@@ -0,0 +1,120 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Starter
|
4
|
+
module Templates
|
5
|
+
module ActiveRecord
|
6
|
+
def model_klass
|
7
|
+
'ActiveRecord::Base'
|
8
|
+
end
|
9
|
+
|
10
|
+
def initializer
|
11
|
+
<<-FILE.strip_heredoc
|
12
|
+
require 'yaml'
|
13
|
+
require 'erb'
|
14
|
+
require 'active_record'
|
15
|
+
|
16
|
+
config_content = File.read(File.join('config', 'database.yml'))
|
17
|
+
|
18
|
+
db_conf = YAML.safe_load(ERB.new(config_content).result)
|
19
|
+
env = ENV['RACK_ENV'] || 'development'
|
20
|
+
|
21
|
+
ActiveRecord::Base.establish_connection db_conf[env]
|
22
|
+
logger = if %w[development test].include? env
|
23
|
+
log_dir = File.join(Dir.getwd, 'log')
|
24
|
+
log_file = File.join(log_dir, 'db.log')
|
25
|
+
FileUtils.mkdir(log_dir) unless Dir.exist?(log_dir)
|
26
|
+
Logger.new(File.open(log_file, 'a'))
|
27
|
+
else
|
28
|
+
Logger.new(STDOUT)
|
29
|
+
end
|
30
|
+
|
31
|
+
ActiveRecord::Base.logger = logger
|
32
|
+
|
33
|
+
# Middleware
|
34
|
+
module ActiveRecord
|
35
|
+
module Rack
|
36
|
+
# ActiveRecord >= 5 removes the Pool management
|
37
|
+
class ConnectionManagement
|
38
|
+
def initialize(app)
|
39
|
+
@app = app
|
40
|
+
end
|
41
|
+
|
42
|
+
def call(env)
|
43
|
+
response = @app.call(env)
|
44
|
+
response[2] = ::Rack::BodyProxy.new(response[2]) do
|
45
|
+
ActiveRecord::Base.clear_active_connections!
|
46
|
+
end
|
47
|
+
|
48
|
+
return response
|
49
|
+
rescue Exception
|
50
|
+
ActiveRecord::Base.clear_active_connections!
|
51
|
+
raise
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
FILE
|
57
|
+
end
|
58
|
+
|
59
|
+
def config # TODO: Dry (Same config for Sequel)
|
60
|
+
<<-FILE.strip_heredoc
|
61
|
+
# ActiveRecord Database Configuration
|
62
|
+
development:
|
63
|
+
adapter: 'sqlite3'
|
64
|
+
host: localhost
|
65
|
+
port: 27017
|
66
|
+
database: "db/development.sqlite3"
|
67
|
+
username:
|
68
|
+
password:
|
69
|
+
|
70
|
+
test:
|
71
|
+
adapter: 'sqlite3'
|
72
|
+
host: localhost
|
73
|
+
port: 27017
|
74
|
+
database: "db/test.sqlite3"
|
75
|
+
username:
|
76
|
+
password:
|
77
|
+
|
78
|
+
production:
|
79
|
+
adapter: 'sqlite3'
|
80
|
+
host: localhost
|
81
|
+
port: 27017
|
82
|
+
database: "db/production.sqlite3"
|
83
|
+
username:
|
84
|
+
password:
|
85
|
+
FILE
|
86
|
+
end
|
87
|
+
|
88
|
+
def rakefile
|
89
|
+
<<-FILE.strip_heredoc
|
90
|
+
# ActiveRecord DB tasks
|
91
|
+
|
92
|
+
task :load_config do
|
93
|
+
config_dir = File.expand_path('../config', __FILE__)
|
94
|
+
config_content = File.read(File.join(config_dir, 'database.yml'))
|
95
|
+
|
96
|
+
DatabaseTasks.env = ENV['RACK_ENV'] || 'development'
|
97
|
+
DatabaseTasks.db_dir = db_dir
|
98
|
+
config = YAML.safe_load(ERB.new(config_content).result)
|
99
|
+
DatabaseTasks.database_configuration = config
|
100
|
+
DatabaseTasks.migrations_paths = File.join(db_dir, 'migrate')
|
101
|
+
|
102
|
+
ActiveRecord::Base.configurations = DatabaseTasks.database_configuration
|
103
|
+
ActiveRecord::Base.establish_connection DatabaseTasks.env.to_sym
|
104
|
+
end
|
105
|
+
|
106
|
+
# Loads AR tasks like db:create, db:drop etc..
|
107
|
+
load 'active_record/railties/databases.rake'
|
108
|
+
FILE
|
109
|
+
end
|
110
|
+
|
111
|
+
def gemfile
|
112
|
+
<<-FILE.strip_heredoc
|
113
|
+
# DB stack
|
114
|
+
gem 'activerecord', '~> 5.1'
|
115
|
+
gem 'sqlite3'
|
116
|
+
FILE
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
@@ -48,12 +48,13 @@ module Starter
|
|
48
48
|
end
|
49
49
|
|
50
50
|
def api_spec
|
51
|
+
prefix = base_prefix ? "/#{base_prefix}" : ''
|
51
52
|
<<-FILE.strip_heredoc
|
52
53
|
# frozen_string_literal: true
|
53
54
|
|
54
55
|
require 'spec_helper'
|
55
56
|
|
56
|
-
RSpec.describe '
|
57
|
+
RSpec.describe '#{prefix}/#{base_version}/#{resource.downcase}' do
|
57
58
|
#{endpoint_specs}
|
58
59
|
end
|
59
60
|
FILE
|
data/lib/starter/config.rb
CHANGED
@@ -10,7 +10,8 @@ module Starter
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def save(dest: Dir.getwd, content: nil)
|
13
|
-
return if content.nil? || content.empty?
|
13
|
+
return if content.nil? || content.empty? || !content.is_a?(Hash)
|
14
|
+
content = read.merge(content)
|
14
15
|
File.open(File.join(dest, '.config'), 'w') { |f| f.write(YAML.dump(content)) }
|
15
16
|
end
|
16
17
|
end
|
data/lib/starter/version.rb
CHANGED
data/template/api/base.rb
CHANGED
data/template/config.ru
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: false
|
2
2
|
|
3
3
|
require 'rack/cors'
|
4
|
+
require_relative 'config/application'
|
4
5
|
|
5
6
|
use Rack::CommonLogger
|
6
7
|
|
@@ -11,6 +12,4 @@ use Rack::Cors do
|
|
11
12
|
end
|
12
13
|
end
|
13
14
|
|
14
|
-
require File.expand_path('../config/application', __FILE__)
|
15
|
-
|
16
15
|
run App.new
|
@@ -16,6 +16,7 @@ class DocApp
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def template
|
19
|
+
prefix = Api::Base.prefix ? "/#{Api::Base.prefix}" : ''
|
19
20
|
"<!DOCTYPE html>
|
20
21
|
<html>
|
21
22
|
<head>
|
@@ -24,7 +25,7 @@ class DocApp
|
|
24
25
|
<style>body {margin: 0;padding: 0;}</style>
|
25
26
|
</head>
|
26
27
|
<body>
|
27
|
-
<redoc spec-url='http://#{server}:#{port}
|
28
|
+
<redoc spec-url='http://#{server}:#{port}#{prefix}/#{Api::Base.version}/oapi.json'></redoc>
|
28
29
|
<script src='https://rebilly.github.io/ReDoc/releases/latest/redoc.min.js'> </script>
|
29
30
|
</body>
|
30
31
|
</html>"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: grape-starter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- LeFnord
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-06-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: gli
|
@@ -93,6 +93,7 @@ files:
|
|
93
93
|
- lib/starter/builder/file_foo.rb
|
94
94
|
- lib/starter/builder/names.rb
|
95
95
|
- lib/starter/builder/orms.rb
|
96
|
+
- lib/starter/builder/templates/activerecord.rb
|
96
97
|
- lib/starter/builder/templates/endpoints.rb
|
97
98
|
- lib/starter/builder/templates/files.rb
|
98
99
|
- lib/starter/builder/templates/sequel.rb
|
@@ -148,7 +149,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
148
149
|
version: '0'
|
149
150
|
requirements: []
|
150
151
|
rubyforge_project:
|
151
|
-
rubygems_version: 2.6.
|
152
|
+
rubygems_version: 2.6.12
|
152
153
|
signing_key:
|
153
154
|
specification_version: 4
|
154
155
|
summary: Create a Grape Rack skeleton
|