lavin 0.1.0 → 0.3.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
- checksums.yaml.gz.sig +0 -0
- data/lib/lavin/client.rb +10 -2
- data/lib/lavin/error.rb +4 -0
- data/lib/lavin/failure.rb +15 -0
- data/lib/lavin/hook.rb +31 -0
- data/lib/lavin/http_client.rb +15 -7
- data/lib/lavin/runner.rb +2 -2
- data/lib/lavin/statistics.rb +67 -10
- data/lib/lavin/stats.rb +29 -3
- data/lib/lavin/step.rb +11 -6
- data/lib/lavin/user.rb +2 -0
- data/lib/lavin/version.rb +1 -1
- data/lib/lavin/web_server.rb +15 -0
- data/lib/lavin/worker.rb +13 -7
- data.tar.gz.sig +0 -0
- metadata +4 -2
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 52a0a48c405e0aff4b816ff7bf91b27e8407929a838db819f8777d222b4f7674
|
|
4
|
+
data.tar.gz: 4acb3c0a928acd45ecbd8137089433e69cdc8235919a0db6fefefb40418bfd82
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e2fe666e13f22d13dc4f085e8ab7e78c2242a973bd9b0d58054e0b4ada2cc17d1ca924e4103a3c55408bd88c4d1cd3efa8b3449cee7fd8a5d36794392218779c
|
|
7
|
+
data.tar.gz: b1f7f478a288492082a4f02462d345ce42703316638b3d6aee7848a92a539b22b750105e5e70fdf2ffe662ac26ed68a4f6a32c63154b18ba4faf96dee917b16b
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
data/lib/lavin/client.rb
CHANGED
|
@@ -5,6 +5,13 @@ require 'async/http/internet'
|
|
|
5
5
|
module Lavin
|
|
6
6
|
class Client
|
|
7
7
|
class Error < Lavin::Error; end
|
|
8
|
+
|
|
9
|
+
class ServerError < Error
|
|
10
|
+
def initialize(status)
|
|
11
|
+
super("Server responded with status: #{status}")
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
8
15
|
class NoCurrentAsyncTaskError < Error
|
|
9
16
|
def initialize(msg = nil)
|
|
10
17
|
super(msg || "Trying to create a client outside of an Async task")
|
|
@@ -17,7 +24,7 @@ module Lavin
|
|
|
17
24
|
}.freeze
|
|
18
25
|
|
|
19
26
|
attr_reader :internet, :base_url
|
|
20
|
-
attr_accessor :request_count, :cookie
|
|
27
|
+
attr_accessor :request_count, :cookie, :report_statistics
|
|
21
28
|
|
|
22
29
|
def initialize(base_url = nil)
|
|
23
30
|
raise NoCurrentAsyncTaskError unless Async::Task.current?
|
|
@@ -26,6 +33,7 @@ module Lavin
|
|
|
26
33
|
@base_url = base_url
|
|
27
34
|
@request_count = 0
|
|
28
35
|
@cookie = nil
|
|
36
|
+
@report_statistics = true
|
|
29
37
|
end
|
|
30
38
|
|
|
31
39
|
def close
|
|
@@ -41,7 +49,7 @@ module Lavin
|
|
|
41
49
|
|
|
42
50
|
status, headers, body = process(response)
|
|
43
51
|
|
|
44
|
-
Statistics.register_request(method:, url:, status:, duration:)
|
|
52
|
+
Statistics.register_request(method:, url:, status:, duration:) if report_statistics
|
|
45
53
|
|
|
46
54
|
{status:, headers:, body: body}
|
|
47
55
|
end
|
data/lib/lavin/error.rb
CHANGED
data/lib/lavin/hook.rb
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Lavin
|
|
4
|
+
class Hook
|
|
5
|
+
attr_reader :user, :block, :type
|
|
6
|
+
|
|
7
|
+
def initialize(user:, type: :before, &block)
|
|
8
|
+
@user = user
|
|
9
|
+
@block = block
|
|
10
|
+
@type = type
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def run(context: nil)
|
|
14
|
+
call(context:)
|
|
15
|
+
Runner.yield
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def call(context:)
|
|
19
|
+
report_statistics = context.client.report_statistics
|
|
20
|
+
context.client.report_statistics = false
|
|
21
|
+
context.instance_exec(&block)
|
|
22
|
+
rescue RecoverableError
|
|
23
|
+
rescue => error
|
|
24
|
+
puts "Caught #{error.class} in #{type} hook: #{error.message}"
|
|
25
|
+
puts error.backtrace unless error.is_a? IrrecoverableError
|
|
26
|
+
throw :failure
|
|
27
|
+
ensure
|
|
28
|
+
context.client.report_statistics = report_statistics
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
data/lib/lavin/http_client.rb
CHANGED
|
@@ -9,7 +9,7 @@ module Lavin
|
|
|
9
9
|
|
|
10
10
|
def initialize(**kwargs)
|
|
11
11
|
super(**kwargs)
|
|
12
|
-
@client = Client.new(config[:base_url])
|
|
12
|
+
@client = kwargs.fetch(:client) { Client.new(config[:base_url]) }
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
def cleanup
|
|
@@ -17,27 +17,35 @@ module Lavin
|
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
def get(url, headers: {})
|
|
20
|
-
|
|
20
|
+
request(:get, url:, headers:)
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
def head(url, headers: {})
|
|
24
|
-
|
|
24
|
+
request(:head, url:, headers:)
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
def post(url, headers: {}, body: nil)
|
|
28
|
-
|
|
28
|
+
request(:post, url:, headers:, body:)
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
def put(url, headers: {}, body: nil)
|
|
32
|
-
|
|
32
|
+
request(:put, url:, headers:, body:)
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
def patch(url, headers: {}, body: nil)
|
|
36
|
-
|
|
36
|
+
request(:patch, url:, headers:, body:)
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
def delete(url, headers: {})
|
|
40
|
-
|
|
40
|
+
request(:delete, url:, headers:)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
private
|
|
44
|
+
|
|
45
|
+
def request(method, url:, headers:, body: nil)
|
|
46
|
+
client.request(method, url:, headers:, body:).tap do |response|
|
|
47
|
+
raise Lavin::Client::ServerError, response[:status] if response[:status] > 499
|
|
48
|
+
end
|
|
41
49
|
end
|
|
42
50
|
end
|
|
43
51
|
end
|
data/lib/lavin/runner.rb
CHANGED
|
@@ -57,14 +57,14 @@ module Lavin
|
|
|
57
57
|
rescue StandardError => error
|
|
58
58
|
puts "Failed to run in thread: #{error.message}"
|
|
59
59
|
thread.join
|
|
60
|
-
thread = nil
|
|
60
|
+
self.thread = nil
|
|
61
61
|
raise
|
|
62
62
|
end
|
|
63
63
|
|
|
64
64
|
def stop
|
|
65
|
-
Statistics.stop
|
|
66
65
|
thread&.kill
|
|
67
66
|
self.thread = nil
|
|
67
|
+
Statistics.stop
|
|
68
68
|
end
|
|
69
69
|
|
|
70
70
|
def running?
|
data/lib/lavin/statistics.rb
CHANGED
|
@@ -28,6 +28,10 @@ module Lavin
|
|
|
28
28
|
data[:total_requests]
|
|
29
29
|
end
|
|
30
30
|
|
|
31
|
+
def total_steps
|
|
32
|
+
data[:step_summary][:count]
|
|
33
|
+
end
|
|
34
|
+
|
|
31
35
|
def duration
|
|
32
36
|
return data[:duration] if data[:duration]
|
|
33
37
|
|
|
@@ -42,8 +46,14 @@ module Lavin
|
|
|
42
46
|
data[:requests][key] << result
|
|
43
47
|
end
|
|
44
48
|
|
|
45
|
-
def register_step
|
|
46
|
-
|
|
49
|
+
def register_step(user:, step_name:, failure: nil)
|
|
50
|
+
data[:step_summary][:count] += 1
|
|
51
|
+
data[:step_summary][:success] += 1 unless failure
|
|
52
|
+
data[:step_summary][:failure] += 1 if failure
|
|
53
|
+
key = [user, step_name]
|
|
54
|
+
data[:steps][key][:success] += 1 unless failure
|
|
55
|
+
data[:steps][key][:failure] += 1 if failure
|
|
56
|
+
data[:failures][failure.to_s] += 1 if failure
|
|
47
57
|
end
|
|
48
58
|
|
|
49
59
|
def stats
|
|
@@ -53,9 +63,11 @@ module Lavin
|
|
|
53
63
|
requests = data[:requests].map do |(method, url), requests|
|
|
54
64
|
durations = []
|
|
55
65
|
statuses = []
|
|
66
|
+
failed_requests = 0
|
|
56
67
|
requests.each do |request|
|
|
57
68
|
durations << request[:duration]
|
|
58
69
|
statuses << request[:status]
|
|
70
|
+
failed_requests += 1 if request[:failure]
|
|
59
71
|
end
|
|
60
72
|
min_duration = durations.min
|
|
61
73
|
max_duration = durations.max
|
|
@@ -66,9 +78,10 @@ module Lavin
|
|
|
66
78
|
url: url,
|
|
67
79
|
requests: requests.size,
|
|
68
80
|
statuses: statuses.tally,
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
81
|
+
failed_requests:,
|
|
82
|
+
avg_duration:,
|
|
83
|
+
min_duration:,
|
|
84
|
+
max_duration:
|
|
72
85
|
}
|
|
73
86
|
end
|
|
74
87
|
|
|
@@ -76,7 +89,10 @@ module Lavin
|
|
|
76
89
|
duration: duration,
|
|
77
90
|
total_requests: total_requests,
|
|
78
91
|
rate: duration ? format("%.2f", total_requests / duration) : 0,
|
|
79
|
-
|
|
92
|
+
step_summary: data[:step_summary],
|
|
93
|
+
steps: data[:steps],
|
|
94
|
+
requests: requests,
|
|
95
|
+
failures: data[:failures]
|
|
80
96
|
).tap do |stats|
|
|
81
97
|
# FIXME remove!
|
|
82
98
|
puts "Calculated stats in #{Time.now - time}s"
|
|
@@ -88,12 +104,24 @@ module Lavin
|
|
|
88
104
|
|
|
89
105
|
show_summary(values)
|
|
90
106
|
|
|
107
|
+
show_steps(values) do |(user, step), hash|
|
|
108
|
+
format(
|
|
109
|
+
"%-48<user_step>s %8<success>d %8<failure>d",
|
|
110
|
+
user_step: "#{user}.#{step}",
|
|
111
|
+
**hash
|
|
112
|
+
)
|
|
113
|
+
end
|
|
114
|
+
|
|
91
115
|
show_table(values) do |request_values|
|
|
92
116
|
format(
|
|
93
117
|
"%-6<method>s %-100<url>s %6<requests>d %12<avg_duration>fs %12<min_duration>fs %12<max_duration>fs",
|
|
94
118
|
**request_values
|
|
95
119
|
)
|
|
96
120
|
end
|
|
121
|
+
|
|
122
|
+
show_failures(values) do |message, count|
|
|
123
|
+
format("%-64<message>s %6<count>d", message:, count:)
|
|
124
|
+
end
|
|
97
125
|
end
|
|
98
126
|
|
|
99
127
|
private
|
|
@@ -116,8 +144,14 @@ module Lavin
|
|
|
116
144
|
start: nil,
|
|
117
145
|
duration: nil,
|
|
118
146
|
total_requests: 0,
|
|
119
|
-
|
|
120
|
-
|
|
147
|
+
step_summary: {
|
|
148
|
+
count: 0,
|
|
149
|
+
success: 0,
|
|
150
|
+
failure: 0
|
|
151
|
+
},
|
|
152
|
+
steps: Hash.new { |h, k| h[k] = {success: 0, failure: 0} },
|
|
153
|
+
requests: Hash.new { |h, k| h[k] = [] },
|
|
154
|
+
failures: Hash.new { |h, k| h[k] = 0 }
|
|
121
155
|
}
|
|
122
156
|
end
|
|
123
157
|
|
|
@@ -127,14 +161,29 @@ module Lavin
|
|
|
127
161
|
Lavin results:
|
|
128
162
|
Test ran for #{values.duration}s
|
|
129
163
|
Total number of requests: #{values.total_requests}
|
|
130
|
-
Rate: #{format("%.2f", values.total_requests/values.duration)} rps
|
|
164
|
+
Rate: #{format("%.2f", values.total_requests / values.duration)} rps
|
|
131
165
|
|
|
166
|
+
Total number of steps: #{values.total_steps}
|
|
167
|
+
Step success rate: #{format("%.2f %%", 100 * values.successful_steps.to_f / values.total_steps)}
|
|
132
168
|
RESULT
|
|
133
169
|
end
|
|
134
170
|
|
|
171
|
+
def show_steps(values)
|
|
172
|
+
puts format(
|
|
173
|
+
"\n%-48<user_step>s %8<success>s %8<failure>s",
|
|
174
|
+
user_step: "Steps",
|
|
175
|
+
success: "Success",
|
|
176
|
+
failure: "Failure"
|
|
177
|
+
)
|
|
178
|
+
divider = "-" * 66
|
|
179
|
+
puts divider
|
|
180
|
+
values.each_step { |step_values| puts yield step_values }
|
|
181
|
+
puts divider
|
|
182
|
+
end
|
|
183
|
+
|
|
135
184
|
def show_table(values)
|
|
136
185
|
puts format(
|
|
137
|
-
"%-6<method>s %-100<url>s %-6<requests>s %12<avg_duration>s %12<min_duration>s %12<max_duration>s",
|
|
186
|
+
"\n%-6<method>s %-100<url>s %-6<requests>s %12<avg_duration>s %12<min_duration>s %12<max_duration>s",
|
|
138
187
|
method: "Method",
|
|
139
188
|
url: "URL",
|
|
140
189
|
requests: "Requests",
|
|
@@ -148,6 +197,14 @@ module Lavin
|
|
|
148
197
|
values.each_request { |request_values| puts yield request_values }
|
|
149
198
|
puts divider
|
|
150
199
|
end
|
|
200
|
+
|
|
201
|
+
def show_failures(values)
|
|
202
|
+
puts format("\n%-64<message>s %6<count>s", message: "Failures", count: "Count")
|
|
203
|
+
divider = "-" * 71
|
|
204
|
+
puts divider
|
|
205
|
+
values.each_failure { |failures| puts yield failures }
|
|
206
|
+
puts divider
|
|
207
|
+
end
|
|
151
208
|
end
|
|
152
209
|
end
|
|
153
210
|
end
|
data/lib/lavin/stats.rb
CHANGED
|
@@ -2,13 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
module Lavin
|
|
4
4
|
class Stats
|
|
5
|
-
attr_reader :duration, :total_requests, :rate, :requests
|
|
5
|
+
attr_reader :duration, :total_requests, :rate, :requests, :step_summary, :steps, :failures
|
|
6
6
|
|
|
7
|
-
def initialize(duration:, total_requests:, rate:, requests: [])
|
|
7
|
+
def initialize(duration:, total_requests:, rate:, requests: [], step_summary: {}, steps: [], failures: [])
|
|
8
8
|
@duration = duration
|
|
9
9
|
@total_requests = total_requests
|
|
10
10
|
@rate = rate
|
|
11
11
|
@requests = requests
|
|
12
|
+
@step_summary = step_summary
|
|
13
|
+
@steps = steps
|
|
14
|
+
@failures = failures
|
|
12
15
|
end
|
|
13
16
|
|
|
14
17
|
def empty?
|
|
@@ -20,12 +23,35 @@ module Lavin
|
|
|
20
23
|
duration:,
|
|
21
24
|
total_requests:,
|
|
22
25
|
rate:,
|
|
23
|
-
requests
|
|
26
|
+
requests:,
|
|
27
|
+
step_summary:,
|
|
28
|
+
steps:,
|
|
29
|
+
failures:
|
|
24
30
|
}
|
|
25
31
|
end
|
|
26
32
|
|
|
33
|
+
def total_steps
|
|
34
|
+
@step_summary[:count]
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def successful_steps
|
|
38
|
+
@step_summary[:success]
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def failed_steps
|
|
42
|
+
@step_summary[:failure]
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def each_step(&block)
|
|
46
|
+
steps.each(&block)
|
|
47
|
+
end
|
|
48
|
+
|
|
27
49
|
def each_request(&block)
|
|
28
50
|
requests.each(&block)
|
|
29
51
|
end
|
|
52
|
+
|
|
53
|
+
def each_failure(&block)
|
|
54
|
+
failures.each(&block)
|
|
55
|
+
end
|
|
30
56
|
end
|
|
31
57
|
end
|
data/lib/lavin/step.rb
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'lavin/error'
|
|
4
|
+
|
|
3
5
|
module Lavin
|
|
4
6
|
class Step
|
|
5
|
-
attr_reader :user, :block, :repeat
|
|
7
|
+
attr_reader :name, :user, :block, :repeat
|
|
6
8
|
|
|
7
|
-
def initialize(repeat: 1, &block)
|
|
9
|
+
def initialize(name:, user:, repeat: 1, &block)
|
|
10
|
+
@name = name
|
|
11
|
+
@user = user
|
|
8
12
|
@repeat = repeat
|
|
9
13
|
@block = block
|
|
10
14
|
end
|
|
@@ -18,11 +22,12 @@ module Lavin
|
|
|
18
22
|
|
|
19
23
|
def call(context:)
|
|
20
24
|
context.instance_exec(&block)
|
|
21
|
-
|
|
25
|
+
Statistics.register_step(user: user.name, step_name: name)
|
|
26
|
+
rescue IrrecoverableError => error
|
|
27
|
+
Statistics.register_step(user: user.name, step_name: name, failure: error.message)
|
|
28
|
+
throw :failure
|
|
22
29
|
rescue => error
|
|
23
|
-
|
|
24
|
-
puts error.backtrace
|
|
25
|
-
# Report Failure!
|
|
30
|
+
Statistics.register_step(user: user.name, step_name: name, failure: error.message)
|
|
26
31
|
end
|
|
27
32
|
end
|
|
28
33
|
end
|
data/lib/lavin/user.rb
CHANGED
|
@@ -4,6 +4,7 @@ require "set"
|
|
|
4
4
|
require "lavin/user_config"
|
|
5
5
|
require "lavin/worker"
|
|
6
6
|
require "lavin/http_client"
|
|
7
|
+
require "lavin/failure"
|
|
7
8
|
|
|
8
9
|
module Lavin
|
|
9
10
|
class User
|
|
@@ -12,6 +13,7 @@ module Lavin
|
|
|
12
13
|
subclass.include UserConfig
|
|
13
14
|
subclass.include Worker
|
|
14
15
|
subclass.include HttpClient
|
|
16
|
+
subclass.include Failure
|
|
15
17
|
all_personas << subclass
|
|
16
18
|
end
|
|
17
19
|
|
data/lib/lavin/version.rb
CHANGED
data/lib/lavin/web_server.rb
CHANGED
|
@@ -40,6 +40,11 @@ module Lavin
|
|
|
40
40
|
redirect to('/statistics')
|
|
41
41
|
end
|
|
42
42
|
|
|
43
|
+
post '/stop' do
|
|
44
|
+
Lavin::Runner.stop
|
|
45
|
+
redirect to('/statistics')
|
|
46
|
+
end
|
|
47
|
+
|
|
43
48
|
get '/statistics' do
|
|
44
49
|
stats = Statistics.stats
|
|
45
50
|
running = Lavin::Runner.running?
|
|
@@ -50,6 +55,16 @@ module Lavin
|
|
|
50
55
|
end
|
|
51
56
|
end
|
|
52
57
|
|
|
58
|
+
get '/failures' do
|
|
59
|
+
stats = Statistics.stats
|
|
60
|
+
running = Lavin::Runner.running?
|
|
61
|
+
if stats.empty? && !running
|
|
62
|
+
redirect to('/')
|
|
63
|
+
else
|
|
64
|
+
erb :failures, locals: {stats:, running:}
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
53
68
|
get '/edit' do
|
|
54
69
|
persona = find_persona
|
|
55
70
|
raise Sinatra::NotFound unless persona
|
data/lib/lavin/worker.rb
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require 'lavin/step'
|
|
4
|
+
require 'lavin/hook'
|
|
4
5
|
|
|
5
6
|
module Lavin
|
|
6
7
|
module Worker
|
|
@@ -8,21 +9,22 @@ module Lavin
|
|
|
8
9
|
def before(&block)
|
|
9
10
|
return @before unless block
|
|
10
11
|
|
|
11
|
-
@before = block
|
|
12
|
+
@before = Hook.new(user: self, type: :before, &block)
|
|
12
13
|
end
|
|
13
14
|
|
|
14
15
|
def after(&block)
|
|
15
16
|
return @after unless block
|
|
16
17
|
|
|
17
|
-
@after = block
|
|
18
|
+
@after = Hook.new(user: self, type: :after, &block)
|
|
18
19
|
end
|
|
19
20
|
|
|
20
21
|
def steps
|
|
21
22
|
@steps ||= []
|
|
22
23
|
end
|
|
23
24
|
|
|
24
|
-
def step(**options, &block)
|
|
25
|
-
|
|
25
|
+
def step(name: nil, **options, &block)
|
|
26
|
+
name ||= "Step##{steps.size + 1}"
|
|
27
|
+
steps << Step.new(user: self, name:, **options, &block)
|
|
26
28
|
end
|
|
27
29
|
end
|
|
28
30
|
|
|
@@ -38,11 +40,15 @@ module Lavin
|
|
|
38
40
|
end
|
|
39
41
|
|
|
40
42
|
def run
|
|
41
|
-
|
|
43
|
+
catch(:failure) do
|
|
44
|
+
self.class.before.run(context: self).then { Runner.yield } if self.class.before
|
|
42
45
|
|
|
43
|
-
|
|
46
|
+
run_step until finished?
|
|
47
|
+
end
|
|
44
48
|
|
|
45
|
-
|
|
49
|
+
catch(:failure) do
|
|
50
|
+
self.class.after.run(context: self).then { Runner.yield } if self.class.after
|
|
51
|
+
end
|
|
46
52
|
end
|
|
47
53
|
|
|
48
54
|
private
|
data.tar.gz.sig
CHANGED
|
Binary file
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: lavin
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Sammy Henningsson
|
|
@@ -29,7 +29,7 @@ cert_chain:
|
|
|
29
29
|
DVzXaUnsmwP+jQ1PkDa5q8ibBzMd2c6Hmm87UDqPxZtML0bF9SjrpbyLMjwtXaMA
|
|
30
30
|
WDPp0ajpdUZ9GPHsrVNYXiOfQIqcmlmpYVsH1o7vuneUIcIDMrnMDChh
|
|
31
31
|
-----END CERTIFICATE-----
|
|
32
|
-
date: 2022-
|
|
32
|
+
date: 2022-11-02 00:00:00.000000000 Z
|
|
33
33
|
dependencies:
|
|
34
34
|
- !ruby/object:Gem::Dependency
|
|
35
35
|
name: async
|
|
@@ -113,6 +113,8 @@ files:
|
|
|
113
113
|
- lib/lavin.rb
|
|
114
114
|
- lib/lavin/client.rb
|
|
115
115
|
- lib/lavin/error.rb
|
|
116
|
+
- lib/lavin/failure.rb
|
|
117
|
+
- lib/lavin/hook.rb
|
|
116
118
|
- lib/lavin/http_client.rb
|
|
117
119
|
- lib/lavin/runner.rb
|
|
118
120
|
- lib/lavin/statistics.rb
|
metadata.gz.sig
CHANGED
|
Binary file
|