pliny 0.31.0 → 1.0.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 +4 -4
- data/lib/pliny/commands/creator.rb +1 -1
- data/lib/pliny/commands/generator/base.rb +1 -1
- data/lib/pliny/db_support.rb +128 -0
- data/lib/pliny/metrics.rb +4 -2
- data/lib/pliny/tasks/db.rake +10 -0
- data/lib/pliny/version.rb +1 -1
- data/lib/template/Gemfile +7 -7
- data/spec/db_support_spec.rb +239 -0
- data/spec/helpers/zulu_time_spec.rb +0 -1
- data/spec/integration_spec.rb +95 -15
- data/spec/metrics_spec.rb +16 -0
- data/spec/spec_helper.rb +1 -0
- metadata +15 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7540ec6b13927224d570bbd316b6210eb0dc1fb9da3ab936e173bd40366f9a19
|
4
|
+
data.tar.gz: 648deaae8ef0a417055fb9ca2916d8961ce49b4c5736c297642bd3650e15acfa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 69869d88363b3f05fe2505a5ae9f9fd6cb60d0ec71ecf5a4037badd49d98637450e6fbc82f594286ff44df773686d0518e565e55f389c6aec7850b7e984d1a1c
|
7
|
+
data.tar.gz: 04d54a2823bcb82ad88aa6188c56167c7dde9abfa64e8b317a96d04047bfa30426fa936bc66cafe342eb38edea084df132c202a3a207fea161ee5ea02308b2ae
|
@@ -35,7 +35,7 @@ module Pliny::Commands
|
|
35
35
|
Dir.glob("#{app_dir}/{*,.*}.erb").each do |file|
|
36
36
|
static_file = file.gsub(/\.erb$/, '')
|
37
37
|
|
38
|
-
template = ERB.new(File.read(file)
|
38
|
+
template = ERB.new(File.read(file))
|
39
39
|
context = OpenStruct.new(app_name: name)
|
40
40
|
content = template.result(context.instance_eval { binding })
|
41
41
|
|
@@ -41,7 +41,7 @@ module Pliny::Commands
|
|
41
41
|
|
42
42
|
def render_template(template_file, vars = {})
|
43
43
|
template_path = File.dirname(__FILE__) + "/../../templates/#{template_file}"
|
44
|
-
template = ERB.new(File.read(template_path),
|
44
|
+
template = ERB.new(File.read(template_path), trim_mode: '>')
|
45
45
|
context = OpenStruct.new(vars)
|
46
46
|
template.result(context.instance_eval { binding })
|
47
47
|
end
|
data/lib/pliny/db_support.rb
CHANGED
@@ -62,6 +62,134 @@ module Pliny
|
|
62
62
|
Integer(version)
|
63
63
|
end
|
64
64
|
|
65
|
+
class MigrationStatus
|
66
|
+
attr_reader :filename
|
67
|
+
attr_accessor :present_on_disk, :present_in_database
|
68
|
+
|
69
|
+
def initialize(filename:)
|
70
|
+
@filename = filename
|
71
|
+
@present_on_disk = false
|
72
|
+
@present_in_database = false
|
73
|
+
end
|
74
|
+
|
75
|
+
def status
|
76
|
+
if present_on_disk
|
77
|
+
if present_in_database
|
78
|
+
:up
|
79
|
+
else
|
80
|
+
:down
|
81
|
+
end
|
82
|
+
else
|
83
|
+
if present_in_database
|
84
|
+
:file_missing
|
85
|
+
else
|
86
|
+
raise "error" # FIXME: better message
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
class MigrationStatusPresenter
|
93
|
+
PADDING = 2
|
94
|
+
UP = "UP".freeze
|
95
|
+
DOWN = "DOWN".freeze
|
96
|
+
FILE_MISSING = "FILE MISSING".freeze
|
97
|
+
|
98
|
+
STATUS_MAP = {
|
99
|
+
up: UP,
|
100
|
+
down: DOWN,
|
101
|
+
file_missing: FILE_MISSING
|
102
|
+
}.freeze
|
103
|
+
|
104
|
+
STATUS_OPTIONS = [
|
105
|
+
UP,
|
106
|
+
DOWN,
|
107
|
+
FILE_MISSING
|
108
|
+
].freeze
|
109
|
+
|
110
|
+
attr_reader :migration_statuses
|
111
|
+
|
112
|
+
def initialize(migration_statuses:)
|
113
|
+
@migration_statuses = migration_statuses
|
114
|
+
end
|
115
|
+
|
116
|
+
def to_s
|
117
|
+
rows.join("\n")
|
118
|
+
end
|
119
|
+
|
120
|
+
def rows
|
121
|
+
header + statuses + footer
|
122
|
+
end
|
123
|
+
|
124
|
+
def header
|
125
|
+
[
|
126
|
+
barrier_row,
|
127
|
+
header_row,
|
128
|
+
barrier_row
|
129
|
+
]
|
130
|
+
end
|
131
|
+
|
132
|
+
def statuses
|
133
|
+
migration_statuses.map { |status|
|
134
|
+
status_row(status)
|
135
|
+
}
|
136
|
+
end
|
137
|
+
|
138
|
+
def footer
|
139
|
+
[
|
140
|
+
barrier_row
|
141
|
+
]
|
142
|
+
end
|
143
|
+
|
144
|
+
def barrier_row
|
145
|
+
"+#{'-' * (longest_status + PADDING)}+#{'-' * (longest_migration_name + PADDING)}+"
|
146
|
+
end
|
147
|
+
|
148
|
+
def header_row
|
149
|
+
"|#{'STATUS'.center(longest_status + PADDING)}|#{'MIGRATION'.center(longest_migration_name + PADDING)}|"
|
150
|
+
end
|
151
|
+
|
152
|
+
def status_row(migration_status)
|
153
|
+
"|#{STATUS_MAP[migration_status.status].center(longest_status + PADDING)}|#{' ' * (PADDING / 2)}#{migration_status.filename.ljust(longest_migration_name)}#{' ' * (PADDING / 2)}|"
|
154
|
+
end
|
155
|
+
|
156
|
+
private
|
157
|
+
|
158
|
+
def longest_migration_name
|
159
|
+
@longest_migration_name ||= migration_statuses.map(&:filename).max_by(&:length).length
|
160
|
+
end
|
161
|
+
|
162
|
+
def longest_status
|
163
|
+
STATUS_OPTIONS.max_by(&:length).length
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
def status
|
168
|
+
migrations_in_database = get_migrations_from_database
|
169
|
+
migrations_on_disk = Dir["#{MIGRATION_DIR}/*.rb"].map { |f| File.basename(f) }
|
170
|
+
total_set_of_migrations = (migrations_in_database | migrations_on_disk).sort_by(&:to_i)
|
171
|
+
|
172
|
+
migration_statuses = total_set_of_migrations.map { |filename|
|
173
|
+
status = MigrationStatus.new(filename: filename)
|
174
|
+
if migrations_on_disk.include?(filename)
|
175
|
+
status.present_on_disk = true
|
176
|
+
end
|
177
|
+
|
178
|
+
if migrations_in_database.include?(filename)
|
179
|
+
status.present_in_database = true
|
180
|
+
end
|
181
|
+
status
|
182
|
+
}
|
183
|
+
|
184
|
+
MigrationStatusPresenter.new(migration_statuses: migration_statuses).to_s
|
185
|
+
end
|
186
|
+
|
187
|
+
def get_migrations_from_database
|
188
|
+
return [] unless db.table_exists?(:schema_migrations)
|
189
|
+
|
190
|
+
db[:schema_migrations].order(Sequel.asc(:filename)).select_map(:filename)
|
191
|
+
end
|
192
|
+
|
65
193
|
def rollback
|
66
194
|
current_version = version
|
67
195
|
return if current_version.zero?
|
data/lib/pliny/metrics.rb
CHANGED
@@ -16,11 +16,13 @@ module Pliny
|
|
16
16
|
counts
|
17
17
|
end
|
18
18
|
|
19
|
-
def measure(*
|
19
|
+
def measure(*inputs, &block)
|
20
20
|
if block
|
21
21
|
elapsed, return_value = time_elapsed(&block)
|
22
22
|
end
|
23
23
|
|
24
|
+
opts = inputs.last.is_a?(Hash) ? inputs.pop : {}
|
25
|
+
|
24
26
|
measurement =
|
25
27
|
if opts.has_key?(:value)
|
26
28
|
opts[:value]
|
@@ -30,7 +32,7 @@ module Pliny
|
|
30
32
|
0
|
31
33
|
end
|
32
34
|
|
33
|
-
measures = Hash[
|
35
|
+
measures = Hash[inputs.map { |n| ["#{Config.app_name}.#{n}", measurement] }]
|
34
36
|
|
35
37
|
backends.each do |backend|
|
36
38
|
report_and_catch { backend.report_measures(measures) }
|
data/lib/pliny/tasks/db.rake
CHANGED
@@ -15,6 +15,16 @@ begin
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
+
namespace :migrate do
|
19
|
+
desc "Get the status of migrations"
|
20
|
+
task :status do
|
21
|
+
# TODO: figure out how to handle multiple databases. Also why do we support multiple databases this way?
|
22
|
+
Pliny::DbSupport.run(database_urls.first, $stdout) do |helper|
|
23
|
+
puts helper.status
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
18
28
|
desc "Run database migrations"
|
19
29
|
task :migrate do
|
20
30
|
next if Dir["./db/migrate/*.rb"].empty?
|
data/lib/pliny/version.rb
CHANGED
data/lib/template/Gemfile
CHANGED
@@ -4,24 +4,24 @@ ruby "2.4.0"
|
|
4
4
|
gem "multi_json"
|
5
5
|
gem "oj"
|
6
6
|
gem "pg"
|
7
|
-
gem "pliny", "~> 0
|
7
|
+
gem "pliny", "~> 1.0"
|
8
8
|
gem "pry"
|
9
|
-
gem "puma", "~>
|
9
|
+
gem "puma", "~> 6"
|
10
10
|
gem "rack-ssl"
|
11
|
-
gem "rack-timeout", "~> 0.
|
11
|
+
gem "rack-timeout", "~> 0.6"
|
12
12
|
gem "rake"
|
13
13
|
gem "rollbar"
|
14
|
-
gem "sequel", "~>
|
14
|
+
gem "sequel", "~> 5.73"
|
15
15
|
gem "sequel-paranoid"
|
16
|
-
gem "sequel_pg", "~> 1.
|
17
|
-
gem "sinatra", [">=
|
16
|
+
gem "sequel_pg", "~> 1.17", require: "sequel"
|
17
|
+
gem "sinatra", [">= 2.0", "< 3.0"], require: "sinatra/base"
|
18
18
|
gem "sinatra-contrib", require: ["sinatra/namespace", "sinatra/reloader"]
|
19
19
|
gem "sinatra-router"
|
20
20
|
gem "sucker_punch"
|
21
21
|
|
22
22
|
group :development, :test do
|
23
23
|
gem "pry-byebug"
|
24
|
-
gem "rubocop", "~>
|
24
|
+
gem "rubocop", "~> 1.56", require: false
|
25
25
|
gem "rubocop-rspec", require: false
|
26
26
|
end
|
27
27
|
|
data/spec/db_support_spec.rb
CHANGED
@@ -114,4 +114,243 @@ describe Pliny::DbSupport do
|
|
114
114
|
end
|
115
115
|
end
|
116
116
|
end
|
117
|
+
|
118
|
+
describe "MigrationStatus" do
|
119
|
+
let(:filename) { "1630551344_latest_change.rb" }
|
120
|
+
let(:migration_status) { described_class::MigrationStatus.new(filename: filename) }
|
121
|
+
|
122
|
+
describe "#status" do
|
123
|
+
context "given a migration present on disk" do
|
124
|
+
before do
|
125
|
+
migration_status.present_on_disk = true
|
126
|
+
end
|
127
|
+
|
128
|
+
context "and present in the database" do
|
129
|
+
before do
|
130
|
+
migration_status.present_in_database = true
|
131
|
+
end
|
132
|
+
|
133
|
+
it "is :up" do
|
134
|
+
assert_equal :up, migration_status.status
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
context "and is absent from the database" do
|
139
|
+
before do
|
140
|
+
migration_status.present_in_database = false
|
141
|
+
end
|
142
|
+
|
143
|
+
it "is :down" do
|
144
|
+
assert_equal :down, migration_status.status
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
context "given a migration absent from disk" do
|
150
|
+
before do
|
151
|
+
migration_status.present_on_disk = false
|
152
|
+
end
|
153
|
+
|
154
|
+
context "and present in the database" do
|
155
|
+
before do
|
156
|
+
migration_status.present_in_database = true
|
157
|
+
end
|
158
|
+
|
159
|
+
it "is :file_missing" do
|
160
|
+
assert_equal :file_missing, migration_status.status
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
context "and is absent from the database" do
|
165
|
+
before do
|
166
|
+
migration_status.present_in_database = false
|
167
|
+
end
|
168
|
+
|
169
|
+
it "is an error case" do
|
170
|
+
assert_raises RuntimeError do
|
171
|
+
migration_status.status
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
describe 'MigrationStatusPresenter' do
|
180
|
+
let(:filename) { '1630551344_latest_change.rb' }
|
181
|
+
let(:up_migration) { described_class::MigrationStatus.new(filename: "00#{filename}") }
|
182
|
+
let(:down_migration) { described_class::MigrationStatus.new(filename: "0#{filename}") }
|
183
|
+
let(:file_missing_migration) { described_class::MigrationStatus.new(filename: "000#{filename}") }
|
184
|
+
let(:migration_statuses) { [up_migration, down_migration, file_missing_migration] }
|
185
|
+
let(:presenter) { described_class::MigrationStatusPresenter.new(migration_statuses: migration_statuses) }
|
186
|
+
|
187
|
+
before do
|
188
|
+
up_migration.present_in_database = true
|
189
|
+
up_migration.present_on_disk = true
|
190
|
+
down_migration.present_in_database = false
|
191
|
+
down_migration.present_on_disk = true
|
192
|
+
file_missing_migration.present_in_database = true
|
193
|
+
file_missing_migration.present_on_disk = false
|
194
|
+
end
|
195
|
+
|
196
|
+
describe '#barrier_row' do
|
197
|
+
it 'pads to the longest_migration name' do
|
198
|
+
expectation = '+--------------+--------------------------------+'
|
199
|
+
assert_equal expectation, presenter.barrier_row
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
describe '#header_row' do
|
204
|
+
it 'pads to the longest migration name' do
|
205
|
+
expectation = '| STATUS | MIGRATION |'
|
206
|
+
assert_equal expectation, presenter.header_row
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
describe '#header' do
|
211
|
+
let(:barrier) { '+--------------+--------------------------------+' }
|
212
|
+
let(:header) { '| STATUS | MIGRATION |' }
|
213
|
+
|
214
|
+
it 'wraps the title in barriers' do
|
215
|
+
assert_equal [barrier, header, barrier], presenter.header
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
describe '#footer' do
|
220
|
+
let(:barrier) { '+--------------+--------------------------------+' }
|
221
|
+
|
222
|
+
it 'just a barrier' do
|
223
|
+
assert_equal [barrier], presenter.footer
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
describe '#status_row' do
|
228
|
+
context 'an up migration' do
|
229
|
+
it 'shows the correct details' do
|
230
|
+
expectation = '| UP | 001630551344_latest_change.rb |'
|
231
|
+
assert_equal expectation, presenter.status_row(up_migration)
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
context 'a down migration' do
|
236
|
+
it 'shows the correct details' do
|
237
|
+
expectation = '| DOWN | 01630551344_latest_change.rb |'
|
238
|
+
assert_equal expectation, presenter.status_row(down_migration)
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
context 'a file missing migration' do
|
243
|
+
it 'shows the correct details' do
|
244
|
+
expectation = '| FILE MISSING | 0001630551344_latest_change.rb |'
|
245
|
+
assert_equal expectation, presenter.status_row(file_missing_migration)
|
246
|
+
end
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
describe '#statuses' do
|
251
|
+
let(:up_expectation) { '| UP | 001630551344_latest_change.rb |' }
|
252
|
+
let(:down_expectation) { '| DOWN | 01630551344_latest_change.rb |' }
|
253
|
+
let(:file_missing_expectation) { '| FILE MISSING | 0001630551344_latest_change.rb |' }
|
254
|
+
|
255
|
+
it 'returns strings' do
|
256
|
+
assert_equal [up_expectation, down_expectation, file_missing_expectation], presenter.statuses
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
describe '#rows' do
|
261
|
+
let(:barrier) { '+--------------+--------------------------------+' }
|
262
|
+
let(:header) { '| STATUS | MIGRATION |' }
|
263
|
+
let(:up_expectation) { '| UP | 001630551344_latest_change.rb |' }
|
264
|
+
let(:down_expectation) { '| DOWN | 01630551344_latest_change.rb |' }
|
265
|
+
let(:file_missing_expectation) { '| FILE MISSING | 0001630551344_latest_change.rb |' }
|
266
|
+
let(:footer) { '+--------------+--------------------------------+' }
|
267
|
+
|
268
|
+
it 'is the table as an array' do
|
269
|
+
expectation = [
|
270
|
+
barrier,
|
271
|
+
header,
|
272
|
+
barrier,
|
273
|
+
up_expectation,
|
274
|
+
down_expectation,
|
275
|
+
file_missing_expectation,
|
276
|
+
footer
|
277
|
+
]
|
278
|
+
|
279
|
+
assert_equal expectation, presenter.rows
|
280
|
+
end
|
281
|
+
end
|
282
|
+
|
283
|
+
describe '#to_s' do
|
284
|
+
it 'is the table as a string' do
|
285
|
+
expectation = <<~OUTPUT.chomp
|
286
|
+
+--------------+--------------------------------+
|
287
|
+
| STATUS | MIGRATION |
|
288
|
+
+--------------+--------------------------------+
|
289
|
+
| UP | 001630551344_latest_change.rb |
|
290
|
+
| DOWN | 01630551344_latest_change.rb |
|
291
|
+
| FILE MISSING | 0001630551344_latest_change.rb |
|
292
|
+
+--------------+--------------------------------+
|
293
|
+
OUTPUT
|
294
|
+
|
295
|
+
assert_equal expectation, presenter.to_s
|
296
|
+
end
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
300
|
+
describe '#status' do
|
301
|
+
let(:filename) { '1630551344_latest_change.rb' }
|
302
|
+
let(:up_migration) { "00#{filename}" }
|
303
|
+
let(:down_migration) { "0#{filename}" }
|
304
|
+
let(:file_missing_migration) { "000#{filename}" }
|
305
|
+
|
306
|
+
before do
|
307
|
+
DB.create_table(:schema_migrations) do
|
308
|
+
text :filename
|
309
|
+
end
|
310
|
+
|
311
|
+
migrations = DB[:schema_migrations]
|
312
|
+
migrations.insert(filename: up_migration)
|
313
|
+
migrations.insert(filename: file_missing_migration)
|
314
|
+
|
315
|
+
File.open("./db/migrate/#{up_migration}", "w") do |f|
|
316
|
+
f.puts "
|
317
|
+
Sequel.migration do
|
318
|
+
change do
|
319
|
+
create_table(:foo) do
|
320
|
+
primary_key :id
|
321
|
+
text :bar
|
322
|
+
end
|
323
|
+
end
|
324
|
+
end
|
325
|
+
"
|
326
|
+
end
|
327
|
+
|
328
|
+
File.open("./db/migrate/#{down_migration}", "w") do |f|
|
329
|
+
f.puts "
|
330
|
+
Sequel.migration do
|
331
|
+
change do
|
332
|
+
create_table(:foo) do
|
333
|
+
primary_key :id
|
334
|
+
text :bar
|
335
|
+
end
|
336
|
+
end
|
337
|
+
end
|
338
|
+
"
|
339
|
+
end
|
340
|
+
end
|
341
|
+
|
342
|
+
it 'returns a table string' do
|
343
|
+
expectation = <<~OUTPUT.chomp
|
344
|
+
+--------------+--------------------------------+
|
345
|
+
| STATUS | MIGRATION |
|
346
|
+
+--------------+--------------------------------+
|
347
|
+
| FILE MISSING | 0001630551344_latest_change.rb |
|
348
|
+
| UP | 001630551344_latest_change.rb |
|
349
|
+
| DOWN | 01630551344_latest_change.rb |
|
350
|
+
+--------------+--------------------------------+
|
351
|
+
OUTPUT
|
352
|
+
|
353
|
+
assert_equal expectation, support.status
|
354
|
+
end
|
355
|
+
end
|
117
356
|
end
|
data/spec/integration_spec.rb
CHANGED
@@ -1,30 +1,45 @@
|
|
1
1
|
require "spec_helper"
|
2
|
+
require "open3"
|
2
3
|
|
3
4
|
describe "Pliny integration test" do
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
bash "pliny-new myapp"
|
5
|
+
describe "bin/setup" do
|
6
|
+
around do |example|
|
7
|
+
original_dir = Dir.pwd
|
8
|
+
test_dir = Dir.mktmpdir("plinytest-")
|
9
|
+
Dir.chdir(test_dir)
|
11
10
|
|
12
|
-
|
13
|
-
bash "bin/setup"
|
14
|
-
end
|
11
|
+
bash "pliny-new myapp"
|
15
12
|
|
16
|
-
|
17
|
-
|
18
|
-
|
13
|
+
Dir.chdir("myapp")
|
14
|
+
example.run
|
15
|
+
Dir.chdir(original_dir)
|
16
|
+
end
|
19
17
|
|
20
|
-
describe "bin/setup" do
|
21
18
|
it "generates .env" do
|
19
|
+
bash "bin/setup"
|
20
|
+
|
22
21
|
assert File.exist?("./.env")
|
23
22
|
end
|
24
23
|
end
|
25
24
|
|
26
25
|
describe "pliny-generate scaffold" do
|
27
|
-
|
26
|
+
around do |example|
|
27
|
+
DB.tables.each { |t| DB.drop_table(t) }
|
28
|
+
|
29
|
+
original_dir = Dir.pwd
|
30
|
+
test_dir = Dir.mktmpdir("plinytest-")
|
31
|
+
Dir.chdir(test_dir)
|
32
|
+
|
33
|
+
bash "pliny-new myapp"
|
34
|
+
|
35
|
+
Dir.chdir("myapp")
|
36
|
+
bash "bin/setup"
|
37
|
+
|
38
|
+
example.run
|
39
|
+
Dir.chdir(original_dir)
|
40
|
+
end
|
41
|
+
|
42
|
+
before do
|
28
43
|
bash "pliny-generate scaffold artist"
|
29
44
|
end
|
30
45
|
|
@@ -45,6 +60,71 @@ describe "Pliny integration test" do
|
|
45
60
|
end
|
46
61
|
end
|
47
62
|
|
63
|
+
describe "rake db:migrate:status" do
|
64
|
+
around do |example|
|
65
|
+
DB.tables.each { |t| DB.drop_table(t) }
|
66
|
+
|
67
|
+
original_dir = Dir.pwd
|
68
|
+
test_dir = Dir.mktmpdir("plinytest-")
|
69
|
+
Dir.chdir(test_dir)
|
70
|
+
|
71
|
+
bash "pliny-new myapp"
|
72
|
+
|
73
|
+
Dir.chdir("myapp")
|
74
|
+
bash "bin/setup"
|
75
|
+
|
76
|
+
example.run
|
77
|
+
Dir.chdir(original_dir)
|
78
|
+
end
|
79
|
+
|
80
|
+
it "returns a migration in the DOWN state when not migrated" do
|
81
|
+
bash "pliny-generate model artist"
|
82
|
+
migration_file = Dir.glob('db/migrate/*').first
|
83
|
+
|
84
|
+
stdout, stderr = bash_with_output("rake db:migrate:status")
|
85
|
+
|
86
|
+
statuses = Hash[stdout.to_s.split(/\+[-]+\+[-]+\+/)[2..-1].map { |s| s.tr("\n", "") }.select(&:present?).map { |s| s.split("|").map { |s| s.tr(" ", "") }.select(&:present?).reverse }]
|
87
|
+
assert statuses[migration_file.split("/").last] == "DOWN"
|
88
|
+
end
|
89
|
+
|
90
|
+
it "returns a migration in the UP state when not migrated" do
|
91
|
+
bash "pliny-generate model artist"
|
92
|
+
migration_file = Dir.glob('db/migrate/*').first
|
93
|
+
bash "rake db:migrate"
|
94
|
+
|
95
|
+
stdout, stderr = bash_with_output("rake db:migrate:status")
|
96
|
+
|
97
|
+
statuses = Hash[stdout.to_s.split(/\+[-]+\+[-]+\+/)[2..-1].map { |s| s.tr("\n", "") }.select(&:present?).map { |s| s.split("|").map { |s| s.tr(" ", "") }.select(&:present?).reverse }]
|
98
|
+
assert statuses[migration_file.split("/").last] == "UP"
|
99
|
+
end
|
100
|
+
|
101
|
+
it "returns a migration in the FILE MISSING state when the file is missing" do
|
102
|
+
bash "pliny-generate model artist"
|
103
|
+
migration_file = Dir.glob('db/migrate/*').first
|
104
|
+
bash "rake db:migrate"
|
105
|
+
|
106
|
+
FileUtils.rm_f(migration_file)
|
107
|
+
|
108
|
+
stdout, stderr = bash_with_output("rake db:migrate:status")
|
109
|
+
|
110
|
+
statuses = Hash[stdout.to_s.split(/\+[-]+\+[-]+\+/)[2..-1].map { |s| s.tr("\n", "") }.select(&:present?).map { |s| s.split("|").map { |s| s.gsub(/(^[ ]+|[ ]+$)/, "") }.select(&:present?).reverse }]
|
111
|
+
assert statuses[migration_file.split("/").last] == "FILE MISSING"
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def bash_with_output(cmd)
|
116
|
+
bin = File.expand_path('../bin', File.dirname(__FILE__))
|
117
|
+
path = "#{bin}:#{ENV["PATH"]}"
|
118
|
+
env = { "PATH" => path }
|
119
|
+
stdout, stderr, status = Open3.capture3(env, cmd)
|
120
|
+
|
121
|
+
unless status.success?
|
122
|
+
raise "Failed to run #{cmd}, error was #{stderr}"
|
123
|
+
end
|
124
|
+
|
125
|
+
return stdout, stderr
|
126
|
+
end
|
127
|
+
|
48
128
|
def bash(cmd)
|
49
129
|
bin = File.expand_path('../bin', File.dirname(__FILE__))
|
50
130
|
path = "#{bin}:#{ENV["PATH"]}"
|
data/spec/metrics_spec.rb
CHANGED
@@ -102,5 +102,21 @@ describe Pliny::Metrics do
|
|
102
102
|
"pliny.waldo" => 0
|
103
103
|
)
|
104
104
|
end
|
105
|
+
|
106
|
+
it "measures value in implicit hash with multiple metrics names" do
|
107
|
+
metrics.measure("metric.name", "another.name", value: 3.14, foo: :bar)
|
108
|
+
expect(test_backend).to have_received(:report_measures).once.with(
|
109
|
+
"pliny.metric.name" => 3.14,
|
110
|
+
"pliny.another.name" => 3.14
|
111
|
+
)
|
112
|
+
end
|
113
|
+
|
114
|
+
it "measures value in explicit hash with multiple metrics names" do
|
115
|
+
metrics.measure("metric.name", "another.name", { value: 3.14, foo: :bar })
|
116
|
+
expect(test_backend).to have_received(:report_measures).once.with(
|
117
|
+
"pliny.metric.name" => 3.14,
|
118
|
+
"pliny.another.name" => 3.14
|
119
|
+
)
|
120
|
+
end
|
105
121
|
end
|
106
122
|
end
|
data/spec/spec_helper.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.
|
4
|
+
version: 1.0.0
|
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:
|
12
|
+
date: 2023-10-09 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
@@ -17,20 +17,20 @@ dependencies:
|
|
17
17
|
requirements:
|
18
18
|
- - ">="
|
19
19
|
- !ruby/object:Gem::Version
|
20
|
-
version:
|
20
|
+
version: '6.0'
|
21
21
|
- - "<"
|
22
22
|
- !ruby/object:Gem::Version
|
23
|
-
version: '
|
23
|
+
version: '8.0'
|
24
24
|
type: :runtime
|
25
25
|
prerelease: false
|
26
26
|
version_requirements: !ruby/object:Gem::Requirement
|
27
27
|
requirements:
|
28
28
|
- - ">="
|
29
29
|
- !ruby/object:Gem::Version
|
30
|
-
version:
|
30
|
+
version: '6.0'
|
31
31
|
- - "<"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '8.0'
|
34
34
|
- !ruby/object:Gem::Dependency
|
35
35
|
name: multi_json
|
36
36
|
requirement: !ruby/object:Gem::Requirement
|
@@ -77,20 +77,20 @@ dependencies:
|
|
77
77
|
requirements:
|
78
78
|
- - ">="
|
79
79
|
- !ruby/object:Gem::Version
|
80
|
-
version: '
|
80
|
+
version: '2.0'
|
81
81
|
- - "<"
|
82
82
|
- !ruby/object:Gem::Version
|
83
|
-
version: '
|
83
|
+
version: '4.0'
|
84
84
|
type: :runtime
|
85
85
|
prerelease: false
|
86
86
|
version_requirements: !ruby/object:Gem::Requirement
|
87
87
|
requirements:
|
88
88
|
- - ">="
|
89
89
|
- !ruby/object:Gem::Version
|
90
|
-
version: '
|
90
|
+
version: '2.0'
|
91
91
|
- - "<"
|
92
92
|
- !ruby/object:Gem::Version
|
93
|
-
version: '
|
93
|
+
version: '4.0'
|
94
94
|
- !ruby/object:Gem::Dependency
|
95
95
|
name: http_accept
|
96
96
|
requirement: !ruby/object:Gem::Requirement
|
@@ -205,20 +205,20 @@ dependencies:
|
|
205
205
|
requirements:
|
206
206
|
- - ">="
|
207
207
|
- !ruby/object:Gem::Version
|
208
|
-
version: '
|
208
|
+
version: '2.0'
|
209
209
|
- - "<"
|
210
210
|
- !ruby/object:Gem::Version
|
211
|
-
version: '
|
211
|
+
version: '4.0'
|
212
212
|
type: :development
|
213
213
|
prerelease: false
|
214
214
|
version_requirements: !ruby/object:Gem::Requirement
|
215
215
|
requirements:
|
216
216
|
- - ">="
|
217
217
|
- !ruby/object:Gem::Version
|
218
|
-
version: '
|
218
|
+
version: '2.0'
|
219
219
|
- - "<"
|
220
220
|
- !ruby/object:Gem::Version
|
221
|
-
version: '
|
221
|
+
version: '4.0'
|
222
222
|
- !ruby/object:Gem::Dependency
|
223
223
|
name: timecop
|
224
224
|
requirement: !ruby/object:Gem::Requirement
|
@@ -512,7 +512,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
512
512
|
- !ruby/object:Gem::Version
|
513
513
|
version: '0'
|
514
514
|
requirements: []
|
515
|
-
rubygems_version: 3.
|
515
|
+
rubygems_version: 3.4.19
|
516
516
|
signing_key:
|
517
517
|
specification_version: 4
|
518
518
|
summary: Basic tooling to support API apps in Sinatra
|