pliny 0.11.0 → 0.11.1
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.
- checksums.yaml +4 -4
- data/README.md +17 -33
- data/lib/pliny/commands/generator.rb +18 -18
- data/lib/pliny/commands/generator/base.rb +1 -3
- data/lib/pliny/middleware/cors.rb +1 -1
- data/lib/pliny/tasks/db.rake +118 -113
- data/lib/pliny/version.rb +1 -1
- data/spec/commands/generator/base_spec.rb +0 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 15e8fffa3d46a900635fa060a7fd577a42e8ee90
|
4
|
+
data.tar.gz: 797a949412bc6f88afc4533fffbab5bc160d66ab
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 51e4c8d782819ab40293e3b2b41b9fcd392e2ead19465f87951bcdd885b9149350c6b49e453918fee945233f3be8e9f7a519281e61c3f752af93656451c99b05
|
7
|
+
data.tar.gz: 15485eccede81da5f81e667fb2f3867fb5a409610db0d08b32c0ac325a5e5b32d0e48e7ac7cfb8209814153566c68bc8d4d4661469001cf7f0b51d7dbc0d7176
|
data/README.md
CHANGED
@@ -1,53 +1,35 @@
|
|
1
1
|
# Pliny
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
[](https://rubygems.org/gems/pliny)
|
5
4
|
[](https://travis-ci.org/interagent/pliny)
|
6
5
|
|
7
|
-
|
8
|
-
|
9
|
-
- Config: `ENV` wrapper for explicit defining what config vars are mandatory and optional
|
10
|
-
- Endpoints: the Sinatra equivalent of a Rails Controller
|
11
|
-
- Initializers: tiny files to configure libraries/etc (equivalent of Rails)
|
12
|
-
- Mediators: plain ruby classes to manipulate models
|
13
|
-
- Models: very thin wrappers around the database
|
14
|
-
|
15
|
-
And gems/helpers to tie these together and support operations:
|
16
|
-
|
17
|
-
- [CORS middleware](lib/pliny/middleware/cors.rb) to allow JS developers to consume your API
|
18
|
-
- [Rollbar](https://www.rollbar.com/) for tracking exceptions
|
19
|
-
- [Log helper](spec/log_spec.rb) that logs in [data format](https://www.youtube.com/watch?v=rpmc-wHFUBs) [to stdout](https://adam.heroku.com/past/2011/4/1/logs_are_streams_not_files)
|
20
|
-
- [Mediators](http://brandur.org/mediator) to help encapsulate more complex interactions
|
21
|
-
- [Rspec](https://github.com/rspec/rspec) for lean and fast testing
|
22
|
-
- [Puma](http://puma.io/) as the web server, [configured for optimal performance on Heroku](lib/template/config/puma.rb)
|
23
|
-
- [Rack-test](https://github.com/brynary/rack-test) to test the API endpoints
|
24
|
-
- [Request IDs](lib/pliny/middleware/request_id.rb)
|
25
|
-
- [RequestStore](http://brandur.org/antipatterns), thread safe option to store data with the current request
|
26
|
-
- [Sequel](http://sequel.jeremyevans.net/) for ORM
|
27
|
-
- [Sequel-PG](https://github.com/jeremyevans/sequel_pg) to talk to the world's most advanced open source database
|
28
|
-
- [Versioning](lib/pliny/middleware/versioning.rb) to allow versioning your API in the HTTP Accept header
|
6
|
+
Pliny helps Ruby developers write and maintain excellent APIs.
|
29
7
|
|
30
|
-
|
8
|
+
It bundles the best patterns, libraries and practices we've seen after writing a lot of APIs.
|
31
9
|
|
32
|
-
First make sure the following is installed:
|
33
10
|
|
34
|
-
|
35
|
-
* The [uuid-ossp](http://www.postgresql.org/docs/9.3/static/uuid-ossp.html) module for Postgres
|
11
|
+
## Resources
|
36
12
|
|
37
|
-
|
13
|
+
- [Documentation](https://github.com/interagent/pliny/wiki)
|
14
|
+
- [Mailing list](https://groups.google.com/group/pliny-talk)
|
15
|
+
|
16
|
+
|
17
|
+
## Getting started
|
18
|
+
|
19
|
+
Install gem:
|
38
20
|
|
39
21
|
```bash
|
40
22
|
$ gem install pliny
|
41
23
|
```
|
42
24
|
|
43
|
-
And initialize
|
25
|
+
And initialize your new API app:
|
44
26
|
|
45
27
|
```bash
|
46
28
|
$ pliny-new myapp
|
47
29
|
$ cd myapp && bin/setup
|
48
30
|
```
|
49
31
|
|
50
|
-
Pliny
|
32
|
+
Pliny bundles [generators](#generators) to help you get started:
|
51
33
|
|
52
34
|
```bash
|
53
35
|
$ bundle exec pliny-generate model artist
|
@@ -106,13 +88,13 @@ Commands:
|
|
106
88
|
|
107
89
|
### Rake tasks
|
108
90
|
|
109
|
-
Pliny
|
91
|
+
Pliny adds common Rake tasks to help maintain your app:
|
110
92
|
|
111
93
|
```bash
|
112
94
|
rake db:create # Create the database
|
113
95
|
rake db:drop # Drop the database
|
114
96
|
rake db:migrate # Run database migrations
|
115
|
-
rake db:rollback # Rollback
|
97
|
+
rake db:rollback # Rollback last database migration
|
116
98
|
rake db:schema:dump # Dump the database schema
|
117
99
|
rake db:schema:load # Load the database schema
|
118
100
|
rake db:schema:merge # Merges migrations into schema and removes them
|
@@ -152,3 +134,5 @@ $ rake
|
|
152
134
|
## Meta
|
153
135
|
|
154
136
|
Created by Brandur Leach and Pedro Belo.
|
137
|
+
|
138
|
+
MIT licensed.
|
@@ -3,9 +3,9 @@ require 'thor'
|
|
3
3
|
|
4
4
|
module Pliny::Commands
|
5
5
|
class Generator < Thor
|
6
|
-
desc 'endpoint
|
6
|
+
desc 'endpoint NAME', 'Generates an endpoint'
|
7
7
|
method_option :scaffold, type: :boolean, default: false, hide: true
|
8
|
-
def endpoint(
|
8
|
+
def endpoint(name)
|
9
9
|
require_relative 'generator/endpoint'
|
10
10
|
|
11
11
|
ep = Endpoint.new(name, options)
|
@@ -14,8 +14,8 @@ module Pliny::Commands
|
|
14
14
|
ep.create_acceptance_test
|
15
15
|
end
|
16
16
|
|
17
|
-
desc 'mediator
|
18
|
-
def mediator(
|
17
|
+
desc 'mediator NAME', 'Generates a mediator'
|
18
|
+
def mediator(name)
|
19
19
|
require_relative 'generator/mediator'
|
20
20
|
|
21
21
|
md = Mediator.new(name, options)
|
@@ -23,17 +23,17 @@ module Pliny::Commands
|
|
23
23
|
md.create_test
|
24
24
|
end
|
25
25
|
|
26
|
-
desc 'migration
|
27
|
-
def migration(
|
26
|
+
desc 'migration NAME', 'Generates a migration'
|
27
|
+
def migration(name)
|
28
28
|
require_relative 'generator/migration'
|
29
29
|
|
30
30
|
mg = Migration.new(name, options)
|
31
31
|
mg.create
|
32
32
|
end
|
33
33
|
|
34
|
-
desc 'model
|
34
|
+
desc 'model NAME', 'Generates a model'
|
35
35
|
method_option :paranoid, type: :boolean, default: false, desc: 'adds paranoid support to model'
|
36
|
-
def model(
|
36
|
+
def model(name)
|
37
37
|
require_relative 'generator/model'
|
38
38
|
|
39
39
|
md = Model.new(name, options)
|
@@ -42,18 +42,18 @@ module Pliny::Commands
|
|
42
42
|
md.create_test
|
43
43
|
end
|
44
44
|
|
45
|
-
desc 'scaffold
|
45
|
+
desc 'scaffold NAME', 'Generates a scaffold of endpoint, model, schema and serializer'
|
46
46
|
method_option :paranoid, type: :boolean, default: false, desc: 'adds paranoid support to model'
|
47
47
|
method_option :scaffold, type: :boolean, default: true, hide: true
|
48
|
-
def scaffold(
|
49
|
-
endpoint(
|
50
|
-
model(
|
51
|
-
schema(
|
52
|
-
serializer(
|
48
|
+
def scaffold(name)
|
49
|
+
endpoint(name)
|
50
|
+
model(name)
|
51
|
+
schema(name)
|
52
|
+
serializer(name)
|
53
53
|
end
|
54
54
|
|
55
|
-
desc 'schema
|
56
|
-
def schema(
|
55
|
+
desc 'schema NAME', 'Generates a schema'
|
56
|
+
def schema(name)
|
57
57
|
require_relative 'generator/schema'
|
58
58
|
|
59
59
|
sc = Schema.new(name, options)
|
@@ -61,8 +61,8 @@ module Pliny::Commands
|
|
61
61
|
sc.rebuild
|
62
62
|
end
|
63
63
|
|
64
|
-
desc 'serializer
|
65
|
-
def serializer(
|
64
|
+
desc 'serializer NAME', 'Generates a serializer'
|
65
|
+
def serializer(name)
|
66
66
|
require_relative 'generator/serializer'
|
67
67
|
|
68
68
|
se = Serializer.new(name, options)
|
@@ -4,7 +4,7 @@ module Pliny::Middleware
|
|
4
4
|
ALLOW_METHODS =
|
5
5
|
%w( GET POST PUT PATCH DELETE OPTIONS ).freeze
|
6
6
|
ALLOW_HEADERS =
|
7
|
-
%w(
|
7
|
+
%w( Content-Type Accept Authorization Cache-Control If-None-Match If-Modified-Since ).freeze
|
8
8
|
EXPOSE_HEADERS =
|
9
9
|
%w( Cache-Control Content-Language Content-Type Expires Last-Modified Pragma ).freeze
|
10
10
|
|
data/lib/pliny/tasks/db.rake
CHANGED
@@ -1,148 +1,153 @@
|
|
1
1
|
require "logger"
|
2
|
-
require "sequel"
|
3
|
-
require "sequel/extensions/migration"
|
4
2
|
require "uri"
|
5
|
-
|
6
|
-
require "pliny/db_support"
|
7
3
|
require "pliny/utils"
|
8
4
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
5
|
+
begin
|
6
|
+
require "sequel"
|
7
|
+
require "sequel/extensions/migration"
|
8
|
+
require "pliny/db_support"
|
9
|
+
|
10
|
+
namespace :db do
|
11
|
+
desc "Run database migrations"
|
12
|
+
task :migrate do
|
13
|
+
next if Dir["./db/migrate/*.rb"].empty?
|
14
|
+
database_urls.each do |database_url|
|
15
|
+
Pliny::DbSupport.run(database_url, $stdout) do |helper|
|
16
|
+
helper.migrate
|
17
|
+
puts "Migrated `#{name_from_uri(database_url)}`"
|
18
|
+
end
|
17
19
|
end
|
18
20
|
end
|
19
|
-
end
|
20
21
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
22
|
+
desc "Rollback last database migration"
|
23
|
+
task :rollback do
|
24
|
+
next if Dir["./db/migrate/*.rb"].empty?
|
25
|
+
database_urls.each do |database_url|
|
26
|
+
Pliny::DbSupport.run(database_url, $stdout) do |helper|
|
27
|
+
helper.rollback
|
28
|
+
puts "Rolled back `#{name_from_uri(database_url)}`"
|
29
|
+
end
|
28
30
|
end
|
29
31
|
end
|
30
|
-
end
|
31
32
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
33
|
+
desc "Seed the database with data"
|
34
|
+
task :seed do
|
35
|
+
if File.exist?('./db/seeds.rb')
|
36
|
+
database_urls.each do |database_url|
|
37
|
+
Sequel.connect(database_url)
|
38
|
+
load 'db/seeds.rb'
|
39
|
+
end
|
40
|
+
disconnect
|
38
41
|
end
|
39
|
-
disconnect
|
40
42
|
end
|
41
|
-
end
|
42
43
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
44
|
+
desc "Create the database"
|
45
|
+
task :create do
|
46
|
+
database_urls.each do |database_url|
|
47
|
+
db_name = name_from_uri(database_url)
|
48
|
+
if Pliny::DbSupport.setup?(database_url)
|
49
|
+
puts "Skipping `#{db_name}`, already exists"
|
50
|
+
else
|
51
|
+
admin_url = Pliny::DbSupport.admin_url(database_url)
|
52
|
+
Pliny::DbSupport.run(admin_url) do |helper|
|
53
|
+
helper.create(db_name)
|
54
|
+
puts "Created `#{db_name}`"
|
55
|
+
end
|
54
56
|
end
|
55
57
|
end
|
58
|
+
disconnect
|
56
59
|
end
|
57
|
-
disconnect
|
58
|
-
end
|
59
60
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
61
|
+
desc "Drop the database"
|
62
|
+
task :drop do
|
63
|
+
database_urls.each do |database_url|
|
64
|
+
admin_url = Pliny::DbSupport.admin_url(database_url)
|
65
|
+
db = Sequel.connect(admin_url)
|
66
|
+
name = name_from_uri(database_url)
|
67
|
+
db.run(%{DROP DATABASE IF EXISTS "#{name}"})
|
68
|
+
puts "Dropped `#{name}`"
|
69
|
+
end
|
70
|
+
disconnect
|
68
71
|
end
|
69
|
-
disconnect
|
70
|
-
end
|
71
72
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
73
|
+
namespace :schema do
|
74
|
+
desc "Load the database schema"
|
75
|
+
task :load do
|
76
|
+
if File.exists?("./db/schema.sql")
|
77
|
+
schema = File.read("./db/schema.sql")
|
78
|
+
database_urls.each do |database_url|
|
79
|
+
db = Sequel.connect(database_url)
|
80
|
+
db.run(schema)
|
81
|
+
puts "Loaded `#{name_from_uri(database_url)}`"
|
82
|
+
end
|
83
|
+
disconnect
|
84
|
+
else
|
85
|
+
puts "Skipped schema load, schema.sql not present"
|
81
86
|
end
|
82
|
-
disconnect
|
83
|
-
else
|
84
|
-
puts "Skipped schema load, schema.sql not present"
|
85
87
|
end
|
86
|
-
end
|
87
88
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
89
|
+
desc "Dump the database schema"
|
90
|
+
task :dump do
|
91
|
+
file = File.join("db", "schema.sql")
|
92
|
+
database_url = database_urls.first
|
93
|
+
`pg_dump -i -s -x -O -f #{file} #{database_url}`
|
94
|
+
|
95
|
+
schema = File.read(file)
|
96
|
+
# filter all COMMENT ON EXTENSION, only owners and the db
|
97
|
+
# superuser can execute these, making it impossible to just
|
98
|
+
# replay such statements in certain production databases
|
99
|
+
schema.gsub!(/^COMMENT ON EXTENSION.*\n/, "")
|
100
|
+
|
101
|
+
# add migrations used to compose this schema
|
102
|
+
db = Sequel.connect(database_urls.first)
|
103
|
+
if db.table_exists?(:schema_migrations)
|
104
|
+
db[:schema_migrations].each do |migration|
|
105
|
+
schema << db[:schema_migrations].insert_sql(migration) + ";\n"
|
106
|
+
end
|
105
107
|
end
|
108
|
+
disconnect
|
109
|
+
|
110
|
+
File.open(file, "w") { |f| f.puts schema }
|
111
|
+
puts "Dumped `#{name_from_uri(database_url)}` to #{file}"
|
106
112
|
end
|
107
|
-
disconnect
|
108
113
|
|
109
|
-
|
110
|
-
|
114
|
+
desc "Merges migrations into schema and removes them"
|
115
|
+
task :merge => ["db:setup", "db:schema:dump"] do
|
116
|
+
FileUtils.rm Dir["./db/migrate/*.rb"]
|
117
|
+
puts "Removed migrations"
|
118
|
+
end
|
111
119
|
end
|
112
120
|
|
113
|
-
desc "
|
114
|
-
task :
|
115
|
-
FileUtils.rm Dir["./db/migrate/*.rb"]
|
116
|
-
puts "Removed migrations"
|
117
|
-
end
|
118
|
-
end
|
121
|
+
desc "Setup the database"
|
122
|
+
task :setup => [:drop, :create, "schema:load", :migrate, :seed]
|
119
123
|
|
120
|
-
|
121
|
-
task :setup => [:drop, :create, "schema:load", :migrate, :seed]
|
124
|
+
private
|
122
125
|
|
123
|
-
|
126
|
+
def disconnect
|
127
|
+
Sequel::DATABASES.each { |db| db.disconnect }
|
128
|
+
Sequel::DATABASES.clear
|
129
|
+
end
|
124
130
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
131
|
+
def database_urls
|
132
|
+
if ENV["DATABASE_URL"]
|
133
|
+
[ENV["DATABASE_URL"]]
|
134
|
+
else
|
135
|
+
%w(.env .env.test).map { |env_file|
|
136
|
+
env_path = "./#{env_file}"
|
137
|
+
if File.exists?(env_path)
|
138
|
+
Pliny::Utils.parse_env(env_path)["DATABASE_URL"]
|
139
|
+
else
|
140
|
+
nil
|
141
|
+
end
|
142
|
+
}.compact
|
143
|
+
end
|
144
|
+
end
|
129
145
|
|
130
|
-
|
131
|
-
|
132
|
-
[ENV["DATABASE_URL"]]
|
133
|
-
else
|
134
|
-
%w(.env .env.test).map { |env_file|
|
135
|
-
env_path = "./#{env_file}"
|
136
|
-
if File.exists?(env_path)
|
137
|
-
Pliny::Utils.parse_env(env_path)["DATABASE_URL"]
|
138
|
-
else
|
139
|
-
nil
|
140
|
-
end
|
141
|
-
}.compact
|
146
|
+
def name_from_uri(uri)
|
147
|
+
URI.parse(uri).path[1..-1]
|
142
148
|
end
|
143
149
|
end
|
144
150
|
|
145
|
-
|
146
|
-
|
147
|
-
end
|
151
|
+
rescue LoadError
|
152
|
+
puts "Couldn't load sequel. Skipping database tasks"
|
148
153
|
end
|
data/lib/pliny/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pliny
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.11.
|
4
|
+
version: 0.11.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brandur Leach
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-08-
|
12
|
+
date: 2015-08-31 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|