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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6ce54496d2a64c456a6d1e1a677478fe0bed3067
4
- data.tar.gz: 853b3d32ba5bd42c64bafaee58ad03fef82fb67f
3
+ metadata.gz: 45c1d0a951be87c5be14c08499f38ae04ccfbbdb
4
+ data.tar.gz: 4b9a797047eaf1271ab0d46a5eb7438043fbddcf
5
5
  SHA512:
6
- metadata.gz: 5d1210d3be1e31da4a12aaf49a536c49bc6f6fcbbcdd06f6831690048428427745f4d82918f821467041c7b6895119df9166d7fc323605c666df28178697a96f
7
- data.tar.gz: d1beec85ca244b47041ff421c96acd47c55db2a154d82ba09dc4e0c9a1f4eddb64bd67bdf135a2627e96e6fa8994aaefbad5f2f395b34ba1560b454516dc7ca2
6
+ metadata.gz: 3c1d2224a49b34e3a9971c663dfd61acbb82f0f487d6e405ce7c83424d050c5227efe0307327e40599724c5f9264f2b5d8e1e0eec6fad535fe7adc1b87f6a473
7
+ data.tar.gz: bc11c7f804027886528c7c2872a68d224b6a02c5e335a582709d2260e34678d0715dfe8bdc287b09e5322cd759d9f311d2758949727a7cf62f536b156e72377c
data/.rubocop_todo.yml CHANGED
@@ -7,7 +7,7 @@
7
7
  # versions of RuboCop, may require this file to be generated again.
8
8
 
9
9
  Metrics/AbcSize:
10
- Max: 20
10
+ Max: 21
11
11
 
12
12
  Metrics/MethodLength:
13
13
  Max: 20
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 also needed files and folders for the specified ORM
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)
@@ -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
- replace_static(File.join('script', 'server'), "API-#{resource}")
38
- replace_static(File.join('api', 'base.rb'), ":#{prefix}")
39
- replace_static(File.join('spec', 'requests', 'root_spec.rb'), prefix)
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
- base_file.scan(/prefix\s+(:.+)\n/).first.first.delete!(':')
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
@@ -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 '/#{base_prefix}/#{base_version}/#{resource.downcase}' do
57
+ RSpec.describe '#{prefix}/#{base_version}/#{resource.downcase}' do
57
58
  #{endpoint_specs}
58
59
  end
59
60
  FILE
@@ -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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Starter
4
- VERSION = '0.7.0'
4
+ VERSION = '0.8.0'
5
5
  end
data/template/api/base.rb CHANGED
@@ -2,9 +2,7 @@
2
2
 
3
3
  module Api
4
4
  class Base < Grape::API
5
- # !!! a prefix is always required
6
- # would be set after project name, to provide a namespace
7
- prefix {{{grape-starter}}}
5
+ {{{grape-starter}}}
8
6
  version 'v1', using: :path
9
7
  format :json
10
8
 
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}/#{Api::Base.prefix}/#{Api::Base.version}/oapi.json'></redoc>
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>"
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- RSpec.describe '/{{{grape-starter}}}/v1/oapi' do
5
+ RSpec.describe '{{{grape-starter}}}/v1/oapi' do
6
6
  subject(:swagger) do
7
7
  get RSpec.current_example.metadata[:example_group][:full_description]
8
8
  last_response
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- RSpec.describe '/{{{grape-starter}}}/v1/root' do
5
+ RSpec.describe '{{{grape-starter}}}/v1/root' do
6
6
  let(:exposed_keys) do
7
7
  %i[
8
8
  verb
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.7.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-05-26 00:00:00.000000000 Z
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.11
152
+ rubygems_version: 2.6.12
152
153
  signing_key:
153
154
  specification_version: 4
154
155
  summary: Create a Grape Rack skeleton