pliny 0.28.0 → 0.31.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4fdeb50812c8474db1b462be06a13943d901cc06c51044c39fffe9533c2d67d4
4
- data.tar.gz: b70639846466fc0efa37a62fc55551ec4386ccfd0ac3141e041bef88744f4610
3
+ metadata.gz: 03b6f9bac86953d6bef8858e6c4c1f6f94f06073fac8175b9572728ffed5a276
4
+ data.tar.gz: c20333f978e5f8e908b13f6eaf9d37a3dbdb0f10204c1db9a8b5f83b02fbac11
5
5
  SHA512:
6
- metadata.gz: f9e248f7961808f6d862d6b77c8065afc7716cf7861ecb0c508d470819ba012a0a0cd2454352b4854bbaad4cb23f18166ace07cca14035eb514ec71fdf908a96
7
- data.tar.gz: 7b7120d718e286d1ecb7cead9ed19db8a823b4aefe66f1601d824cfc172b46c89c2cbbe2ebdccfaf0e113b8afb862bd2c85d76bf55438ca1dbd5ea89bfc3f28d
6
+ metadata.gz: e851ccdd1fb0a3d548fa672d209829e9cd8ecf69023d1c7a2fb6ad0fb84ee1616d2d3b2a761d11ba9c13a989d2fb5176c31d3eb6acf9a02e20c6e7bc4b01386f
7
+ data.tar.gz: aefb3c02dc44ba282595bb9b2e85dc52e2891cb16ac6395693ab63bd79c603b7c68e9b93dea4c494c1b574e8be308b26a34e40040d4e71e0a74cb9a9f828a207
data/README.md CHANGED
@@ -1,7 +1,8 @@
1
1
  # Pliny
2
2
 
3
3
  [![Gem version](http://img.shields.io/gem/v/pliny.svg)](https://rubygems.org/gems/pliny)
4
- [![Build Status](https://travis-ci.org/interagent/pliny.svg?branch=master)](https://travis-ci.org/interagent/pliny)
4
+ [![Github Actions CI](https://github.com/interagent/pliny/actions/workflows/ruby.yml/badge.svg)](https://github.com/interagent/pliny/actions)
5
+
5
6
 
6
7
  Pliny helps Ruby developers write and maintain excellent APIs.
7
8
 
@@ -46,25 +46,43 @@ module Pliny
46
46
  db.run(%{CREATE DATABASE "#{name}"})
47
47
  end
48
48
 
49
- def migrate(target=nil)
50
- Sequel::Migrator.apply(db, "./db/migrate", target)
49
+ def migrate(target = nil)
50
+ Sequel::Migrator.apply(db, MIGRATION_DIR, target)
51
+ end
52
+
53
+ def version
54
+ return 0 unless db.table_exists?(:schema_migrations)
55
+
56
+ current = db[:schema_migrations].order(Sequel.desc(:filename)).first
57
+
58
+ return 0 unless current
59
+
60
+ version = current[:filename].match(Sequel::Migrator::MIGRATION_FILE_PATTERN).captures.first
61
+ version ||= 0
62
+ Integer(version)
51
63
  end
52
64
 
53
65
  def rollback
54
- return unless db.tables.include?(:schema_migrations)
55
- return unless current = db[:schema_migrations].order(Sequel.desc(:filename)).first
66
+ current_version = version
67
+ return if current_version.zero?
68
+
69
+ migrations = Dir["#{MIGRATION_DIR}/*.rb"].map { |f| File.basename(f).to_i }.sort
56
70
 
57
- migrations = Dir["./db/migrate/*.rb"].map { |f| File.basename(f).to_i }.sort
58
- target = 0 # by default, rollback everything
59
- index = migrations.index(current[:filename].to_i)
71
+ target = 0 # by default, rollback everything
72
+ index = migrations.index(current_version)
60
73
  if index > 0
61
74
  target = migrations[index - 1]
62
75
  end
63
- Sequel::Migrator.apply(db, "./db/migrate", target)
76
+ Sequel::Migrator.apply(db, MIGRATION_DIR, target)
64
77
  end
65
78
 
66
79
  def disconnect
67
80
  @db.disconnect
68
81
  end
82
+
83
+ private
84
+
85
+ MIGRATION_DIR = "./db/migrate".freeze
86
+ private_constant :MIGRATION_DIR
69
87
  end
70
88
  end
@@ -8,9 +8,13 @@ module Pliny::Helpers
8
8
 
9
9
  def parse_body_params
10
10
  if request.media_type == "application/json"
11
- p = load_params(MultiJson.decode(request.body.read))
11
+ begin
12
+ decoded = MultiJson.decode(request.body.read)
13
+ rescue MultiJson::ParseError => e
14
+ raise Pliny::Errors::BadRequest, e.message
15
+ end
12
16
  request.body.rewind
13
- p
17
+ load_params(decoded)
14
18
  elsif request.form_data?
15
19
  load_params(request.POST)
16
20
  else
@@ -1,42 +1,41 @@
1
1
  module Pliny::Helpers
2
2
  module Serialize
3
- def self.included(base)
4
- base.send :extend, ClassMethods
3
+ def self.registered(base)
4
+ base.helpers Helpers
5
+ base.set :serializer_class, nil
5
6
  end
6
7
 
7
- def serialize(data, structure = :default)
8
- serializer_class = self.class.serializer_class
8
+ module Helpers
9
+ def serialize(data, structure = :default)
10
+ serializer_class = settings.serializer_class
9
11
 
10
- if serializer_class.nil?
11
- raise <<-eos.strip
12
- No serializer has been specified for this endpoint. Please specify one with
13
- `serializer Serializers::ModelName` in the endpoint.
14
- eos
15
- end
12
+ if serializer_class.nil?
13
+ raise <<~eos.strip
14
+ No serializer has been specified for this endpoint. Please specify one with
15
+ `serializer Serializers::ModelName` in the endpoint.
16
+ eos
17
+ end
16
18
 
17
- env['pliny.serializer_arity'] = data.respond_to?(:size) ? data.size : 1
19
+ env['pliny.serializer_arity'] = data.respond_to?(:size) ? data.size : 1
18
20
 
19
- start = Time.now
20
- serializer_class.new(structure).serialize(data).tap do
21
- env['pliny.serializer_timing'] = (Time.now - start).to_f
21
+ start = Time.now
22
+ serializer_class.new(structure).serialize(data).tap do
23
+ env['pliny.serializer_timing'] = (Time.now - start).to_f
24
+ end
22
25
  end
23
26
  end
24
27
 
25
- module ClassMethods
26
- # Provide a way to specify endpoint serializer class.
27
- #
28
- # class Endpoints::User < Base
29
- # serializer Serializers::User
30
- #
31
- # get do
32
- # encode serialize(User.all)
33
- # end
34
- # end
35
- def serializer(serializer_class)
36
- @serializer_class = serializer_class
37
- end
38
-
39
- attr_reader :serializer_class
28
+ # Provide a way to specify endpoint serializer class.
29
+ #
30
+ # class Endpoints::User < Base
31
+ # serializer Serializers::User
32
+ #
33
+ # get do
34
+ # encode serialize(User.all)
35
+ # end
36
+ # end
37
+ def serializer(serializer_class)
38
+ set :serializer_class, serializer_class
40
39
  end
41
40
  end
42
41
  end
data/lib/pliny/log.rb CHANGED
@@ -123,13 +123,17 @@ module Pliny
123
123
  end
124
124
  end
125
125
 
126
- def quote_string(k, v)
126
+ def replace_newlines(v)
127
+ v.gsub("\n", "\\n")
128
+ end
129
+
130
+ def quote_string(v)
127
131
  if !v.include?('"')
128
- %{#{k}="#{v}"}
132
+ %{"#{v}"}
129
133
  elsif !v.include?("'")
130
- %{#{k}='#{v}'}
134
+ %{'#{v}'}
131
135
  else
132
- %{#{k}="#{v.gsub(/"/, '\\"')}"}
136
+ %{"#{v.gsub(/"/, '\\"')}"}
133
137
  end
134
138
  end
135
139
 
@@ -150,11 +154,10 @@ module Pliny
150
154
  "#{k}=#{v.iso8601}"
151
155
  else
152
156
  v = "#{v}"
153
- if v =~ /\s/
154
- quote_string(k, v)
155
- else
156
- "#{k}=#{v}"
157
- end
157
+ v = replace_newlines(v)
158
+ v = quote_string(v) if v =~ /\s/
159
+
160
+ "#{k}=#{v}"
158
161
  end
159
162
  end
160
163
  end
@@ -58,9 +58,9 @@ module Pliny::Middleware
58
58
  log_field :timing_serializer, Float
59
59
  end
60
60
 
61
- def initialize(app, emitter:)
61
+ def initialize(app, options)
62
62
  @app = app
63
- @emitter = emitter
63
+ @emitter = options.fetch(:emitter)
64
64
  end
65
65
 
66
66
  def call(env)
@@ -8,6 +8,13 @@ begin
8
8
  require "pliny/db_support"
9
9
 
10
10
  namespace :db do
11
+ desc "Get current schema version"
12
+ task :version do
13
+ Pliny::DbSupport.run(database_urls.first, $stdout) do |helper|
14
+ puts "Current version: #{helper.version}"
15
+ end
16
+ end
17
+
11
18
  desc "Run database migrations"
12
19
  task :migrate do
13
20
  next if Dir["./db/migrate/*.rb"].empty?
data/lib/pliny/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Pliny
2
- VERSION = "0.28.0"
2
+ VERSION = "0.31.0"
3
3
  end
data/lib/template/Gemfile CHANGED
@@ -4,7 +4,7 @@ ruby "2.4.0"
4
4
  gem "multi_json"
5
5
  gem "oj"
6
6
  gem "pg"
7
- gem "pliny", "~> 0.28"
7
+ gem "pliny", "~> 0.31"
8
8
  gem "pry"
9
9
  gem "puma", "~> 3"
10
10
  gem "rack-ssl"
@@ -5,7 +5,7 @@ module Endpoints
5
5
 
6
6
  helpers Pliny::Helpers::Encode
7
7
  helpers Pliny::Helpers::Params
8
- helpers Pliny::Helpers::Serialize
8
+ register Pliny::Helpers::Serialize
9
9
 
10
10
  set :dump_errors, false
11
11
  set :raise_errors, true
@@ -2,9 +2,9 @@ require "spec_helper"
2
2
  require "pliny/db_support"
3
3
 
4
4
  describe Pliny::DbSupport do
5
+ subject(:support) { Pliny::DbSupport.new(url, logger) }
5
6
  let(:url) { ENV["TEST_DATABASE_URL"] }
6
7
  let(:logger) { Logger.new(StringIO.new) }
7
- let(:support) { Pliny::DbSupport.new(url, logger) }
8
8
 
9
9
  around do |example|
10
10
  Dir.mktmpdir("plinytest-") do |dir|
@@ -88,4 +88,30 @@ describe Pliny::DbSupport do
88
88
  support.rollback # should noop
89
89
  end
90
90
  end
91
+
92
+ describe "#version" do
93
+ it "is zero if the migrations table doesn't exist" do
94
+ assert_equal 0, support.version
95
+ end
96
+
97
+ context "with migrations table" do
98
+ before do
99
+ DB.create_table(:schema_migrations) do
100
+ text :filename
101
+ end
102
+ end
103
+
104
+ it "is zero if the migrations table is empty" do
105
+ assert_equal 0, support.version
106
+ end
107
+
108
+ it "is the highest timestamp from a filename in the migrations table" do
109
+ migrations = DB[:schema_migrations]
110
+ migrations.insert(filename: "1630551344_latest_change.rb")
111
+ migrations.insert(filename: "1524000760_earlier_change.rb")
112
+
113
+ assert_equal 1630551344, support.version
114
+ end
115
+ end
116
+ end
91
117
  end
@@ -34,4 +34,12 @@ describe Pliny::Helpers::Params do
34
34
  post "/", "<hello>world</hello>", {"CONTENT_TYPE" => "application/xml"}
35
35
  assert_equal "{}", last_response.body
36
36
  end
37
+
38
+ it "should throw bad request when receiving invalid json via post" do
39
+ err = assert_raises(Pliny::Errors::BadRequest) do
40
+ post "/", "{\"foo\"}", {"CONTENT_TYPE" => "application/json"}
41
+ end
42
+
43
+ assert_match /unexpected token/, err.message
44
+ end
37
45
  end
@@ -4,7 +4,7 @@ describe Pliny::Helpers::Serialize do
4
4
  context "without a serializer" do
5
5
  def app
6
6
  Sinatra.new do
7
- helpers Pliny::Helpers::Serialize
7
+ register Pliny::Helpers::Serialize
8
8
 
9
9
  get "/" do
10
10
  MultiJson.encode(serialize([]))
@@ -29,7 +29,7 @@ describe Pliny::Helpers::Serialize do
29
29
 
30
30
  def app
31
31
  Sinatra.new do
32
- helpers Pliny::Helpers::Serialize
32
+ register Pliny::Helpers::Serialize
33
33
 
34
34
  serializer Serializer
35
35
 
data/spec/log_spec.rb CHANGED
@@ -161,6 +161,12 @@ describe Pliny::Log do
161
161
  Pliny.log(foo: "string with spaces")
162
162
  end
163
163
 
164
+ it "replaces newlines in strings" do
165
+ expect(@io).to receive(:print).with("foo=\"string\\nwith newlines\\n\"\n")
166
+
167
+ Pliny.log(foo: "string\nwith newlines\n")
168
+ end
169
+
164
170
  it "by default interpolates objects into strings" do
165
171
  expect(@io).to receive(:print).with("foo=message\n")
166
172
  expect(@io).to receive(:print).with("foo=42\n")
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pliny
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.28.0
4
+ version: 0.31.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brandur Leach
8
8
  - Pedro Belo
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2020-05-08 00:00:00.000000000 Z
12
+ date: 2021-09-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -135,22 +135,22 @@ dependencies:
135
135
  name: thor
136
136
  requirement: !ruby/object:Gem::Requirement
137
137
  requirements:
138
- - - "~>"
138
+ - - ">="
139
139
  - !ruby/object:Gem::Version
140
140
  version: '0.19'
141
- - - ">="
141
+ - - "<"
142
142
  - !ruby/object:Gem::Version
143
- version: 0.19.1
143
+ version: '2.0'
144
144
  type: :runtime
145
145
  prerelease: false
146
146
  version_requirements: !ruby/object:Gem::Requirement
147
147
  requirements:
148
- - - "~>"
148
+ - - ">="
149
149
  - !ruby/object:Gem::Version
150
150
  version: '0.19'
151
- - - ">="
151
+ - - "<"
152
152
  - !ruby/object:Gem::Version
153
- version: 0.19.1
153
+ version: '2.0'
154
154
  - !ruby/object:Gem::Dependency
155
155
  name: rake
156
156
  requirement: !ruby/object:Gem::Requirement
@@ -183,22 +183,22 @@ dependencies:
183
183
  name: rspec
184
184
  requirement: !ruby/object:Gem::Requirement
185
185
  requirements:
186
- - - ">="
187
- - !ruby/object:Gem::Version
188
- version: 3.1.0
189
186
  - - "~>"
190
187
  - !ruby/object:Gem::Version
191
188
  version: '3.1'
189
+ - - ">="
190
+ - !ruby/object:Gem::Version
191
+ version: 3.1.0
192
192
  type: :development
193
193
  prerelease: false
194
194
  version_requirements: !ruby/object:Gem::Requirement
195
195
  requirements:
196
- - - ">="
197
- - !ruby/object:Gem::Version
198
- version: 3.1.0
199
196
  - - "~>"
200
197
  - !ruby/object:Gem::Version
201
198
  version: '3.1'
199
+ - - ">="
200
+ - !ruby/object:Gem::Version
201
+ version: 3.1.0
202
202
  - !ruby/object:Gem::Dependency
203
203
  name: sinatra-contrib
204
204
  requirement: !ruby/object:Gem::Requirement
@@ -273,60 +273,54 @@ dependencies:
273
273
  requirements:
274
274
  - - "~>"
275
275
  - !ruby/object:Gem::Version
276
- version: '0.17'
277
- - - ">="
276
+ version: '1.0'
277
+ - - "<"
278
278
  - !ruby/object:Gem::Version
279
- version: 0.17.1
279
+ version: '2.0'
280
280
  type: :development
281
281
  prerelease: false
282
282
  version_requirements: !ruby/object:Gem::Requirement
283
283
  requirements:
284
284
  - - "~>"
285
285
  - !ruby/object:Gem::Version
286
- version: '0.17'
287
- - - ">="
286
+ version: '1.0'
287
+ - - "<"
288
288
  - !ruby/object:Gem::Version
289
- version: 0.17.1
289
+ version: '2.0'
290
290
  - !ruby/object:Gem::Dependency
291
291
  name: rollbar
292
292
  requirement: !ruby/object:Gem::Requirement
293
293
  requirements:
294
- - - ">="
295
- - !ruby/object:Gem::Version
296
- version: 2.11.0
297
294
  - - "~>"
298
295
  - !ruby/object:Gem::Version
299
- version: '2.11'
296
+ version: '3.2'
300
297
  type: :development
301
298
  prerelease: false
302
299
  version_requirements: !ruby/object:Gem::Requirement
303
300
  requirements:
304
- - - ">="
305
- - !ruby/object:Gem::Version
306
- version: 2.11.0
307
301
  - - "~>"
308
302
  - !ruby/object:Gem::Version
309
- version: '2.11'
303
+ version: '3.2'
310
304
  - !ruby/object:Gem::Dependency
311
305
  name: sequel
312
306
  requirement: !ruby/object:Gem::Requirement
313
307
  requirements:
314
- - - ">="
315
- - !ruby/object:Gem::Version
316
- version: 4.9.0
317
308
  - - "~>"
318
309
  - !ruby/object:Gem::Version
319
- version: '4.9'
310
+ version: '5.4'
311
+ - - "<"
312
+ - !ruby/object:Gem::Version
313
+ version: '6.0'
320
314
  type: :development
321
315
  prerelease: false
322
316
  version_requirements: !ruby/object:Gem::Requirement
323
317
  requirements:
324
- - - ">="
325
- - !ruby/object:Gem::Version
326
- version: 4.9.0
327
318
  - - "~>"
328
319
  - !ruby/object:Gem::Version
329
- version: '4.9'
320
+ version: '5.4'
321
+ - - "<"
322
+ - !ruby/object:Gem::Version
323
+ version: '6.0'
330
324
  - !ruby/object:Gem::Dependency
331
325
  name: rubocop
332
326
  requirement: !ruby/object:Gem::Requirement
@@ -503,7 +497,7 @@ homepage: https://github.com/interagent/pliny
503
497
  licenses:
504
498
  - MIT
505
499
  metadata: {}
506
- post_install_message:
500
+ post_install_message:
507
501
  rdoc_options: []
508
502
  require_paths:
509
503
  - lib
@@ -518,8 +512,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
518
512
  - !ruby/object:Gem::Version
519
513
  version: '0'
520
514
  requirements: []
521
- rubygems_version: 3.0.3
522
- signing_key:
515
+ rubygems_version: 3.1.6
516
+ signing_key:
523
517
  specification_version: 4
524
518
  summary: Basic tooling to support API apps in Sinatra
525
519
  test_files: []