peak_flow_utils 0.1.14 → 0.1.15
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/app/services/peak_flow_utils/deep_merger.rb +45 -0
- data/lib/peak_flow_utils/notifier.rb +38 -3
- data/lib/peak_flow_utils/notifier_rack.rb +6 -6
- data/lib/peak_flow_utils/version.rb +1 -1
- data/lib/peak_flow_utils.rb +0 -1
- metadata +7 -9
- data/bin/peak_flow_rspec_files +0 -21
- data/lib/peak_flow_utils/rspec_helper.rb +0 -209
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b4fb7a276f751a58ba19b74e73955323e0f1b89215312b50ee3e3b9cf89a85f4
|
4
|
+
data.tar.gz: 29edd9b2f4225cf2ea74c67d4fccd1b21a0149781f2cacc168309ef8dd3082c6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 18328934879ae9fbb148e812926d68b5dca82837f929e5c3f3228bc4bc34bb140e8d42013333ef68976931819960d45110b26a8bf8bb2b37e363b8a519bf0ee9
|
7
|
+
data.tar.gz: 4251f1f1213fc0e9dfa426c7c4a1e75c53dbd23dff37ce09213f857ff7b7fba56251875d17a7baed74273d744f29b03bd9fa3e41f7a877319ada3cf9760bf9b4
|
@@ -0,0 +1,45 @@
|
|
1
|
+
class PeakFlowUtils::DeepMerger < PeakFlowUtils::ApplicationService
|
2
|
+
def initialize(hashes:)
|
3
|
+
@hashes = hashes
|
4
|
+
end
|
5
|
+
|
6
|
+
def perform
|
7
|
+
merged = {}
|
8
|
+
|
9
|
+
@hashes.each do |hash|
|
10
|
+
merge_hash(hash, merged)
|
11
|
+
end
|
12
|
+
|
13
|
+
succeed! merged
|
14
|
+
end
|
15
|
+
|
16
|
+
def merge_something(object, merged)
|
17
|
+
if object.is_a?(Array)
|
18
|
+
merge_array(object, merged)
|
19
|
+
elsif object.is_a?(Hash)
|
20
|
+
merge_hash(object, merged)
|
21
|
+
else
|
22
|
+
raise "Unknown object: #{object.class.name}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def merge_array(array, merged)
|
27
|
+
array.each do |value|
|
28
|
+
merged << value
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def merge_hash(hash, merged)
|
33
|
+
hash.each do |key, value|
|
34
|
+
if !merged.key?(key)
|
35
|
+
merged[key] = value
|
36
|
+
elsif value.is_a?(Array)
|
37
|
+
merge_array(value, merged[key])
|
38
|
+
elsif value.is_a?(Hash)
|
39
|
+
merge_hash(value, merged[key])
|
40
|
+
else
|
41
|
+
raise "Unknown object: #{object.class.name}"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -14,8 +14,41 @@ class PeakFlowUtils::Notifier
|
|
14
14
|
@current
|
15
15
|
end
|
16
16
|
|
17
|
-
def self.
|
18
|
-
PeakFlowUtils::Notifier.
|
17
|
+
def self.current_parameters(parameters: nil)
|
18
|
+
hashes = PeakFlowUtils::Notifier.current_parameters_hashes
|
19
|
+
hashes << parameters if parameters
|
20
|
+
|
21
|
+
PeakFlowUtils::DeepMerger.execute!(hashes: hashes)
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.current_parameters_hashes
|
25
|
+
hashes = []
|
26
|
+
|
27
|
+
Thread.current[:peakflow_utils] ||= {}
|
28
|
+
Thread.current[:peakflow_utils].dig(:notifier, :with_parameters)&.each_value do |more_parameters|
|
29
|
+
hashes << more_parameters
|
30
|
+
end
|
31
|
+
|
32
|
+
hashes
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.notify(*args, **opts, &blk)
|
36
|
+
PeakFlowUtils::Notifier.current.notify(*args, **opts, &blk)
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.with_parameters(parameters)
|
40
|
+
random_id = SecureRandom.hex(16)
|
41
|
+
|
42
|
+
Thread.current[:peakflow_utils] ||= {}
|
43
|
+
Thread.current[:peakflow_utils][:notifier] ||= {}
|
44
|
+
Thread.current[:peakflow_utils][:notifier][:with_parameters] ||= {}
|
45
|
+
Thread.current[:peakflow_utils][:notifier][:with_parameters][random_id] = parameters
|
46
|
+
|
47
|
+
begin
|
48
|
+
yield
|
49
|
+
ensure
|
50
|
+
Thread.current[:peakflow_utils][:notifier][:with_parameters].delete(random_id)
|
51
|
+
end
|
19
52
|
end
|
20
53
|
|
21
54
|
def initialize(auth_token:)
|
@@ -29,6 +62,8 @@ class PeakFlowUtils::Notifier
|
|
29
62
|
error: error
|
30
63
|
)
|
31
64
|
|
65
|
+
merged_parameters = PeakFlowUtils::Notifier.current_parameters(parameters: parameters)
|
66
|
+
|
32
67
|
uri = URI("https://www.peakflow.io/errors/reports")
|
33
68
|
|
34
69
|
https = Net::HTTP.new(uri.host, uri.port)
|
@@ -43,7 +78,7 @@ class PeakFlowUtils::Notifier
|
|
43
78
|
file_path: error_parser.file_path,
|
44
79
|
line_number: error_parser.line_number,
|
45
80
|
message: error.message,
|
46
|
-
parameters:
|
81
|
+
parameters: merged_parameters,
|
47
82
|
remote_ip: error_parser.remote_ip,
|
48
83
|
url: error_parser.url,
|
49
84
|
user_agent: error_parser.user_agent
|
@@ -9,13 +9,13 @@ class PeakFlowUtils::NotifierRack
|
|
9
9
|
rescue Exception => e # rubocop:disable Lint/RescueException
|
10
10
|
controller = env["action_controller.instance"]
|
11
11
|
request = controller&.request
|
12
|
-
parameters = {}.merge(request.GET).merge(request.POST)
|
13
12
|
|
14
|
-
PeakFlowUtils::Notifier.
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
13
|
+
PeakFlowUtils::Notifier.with_parameters(rack: {get: request.GET, post: request.POST}) do
|
14
|
+
PeakFlowUtils::Notifier.notify(
|
15
|
+
environment: env,
|
16
|
+
error: e
|
17
|
+
)
|
18
|
+
end
|
19
19
|
|
20
20
|
raise e
|
21
21
|
end
|
data/lib/peak_flow_utils.rb
CHANGED
@@ -13,7 +13,6 @@ module PeakFlowUtils
|
|
13
13
|
autoload :NotifierRails, "#{path}/notifier_rails"
|
14
14
|
autoload :NotifierResponse, "#{path}/notifier_response"
|
15
15
|
autoload :NotifierSidekiq, "#{path}/notifier_sidekiq"
|
16
|
-
autoload :RspecHelper, "#{path}/rspec_helper"
|
17
16
|
autoload :HandlerHelper, "#{path}/handler_helper"
|
18
17
|
|
19
18
|
autoload :ApplicationRecord, "#{models_path}/application_record"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: peak_flow_utils
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.15
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- kaspernj
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-02-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -58,14 +58,14 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 1.0.
|
61
|
+
version: 1.0.5
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: 1.0.
|
68
|
+
version: 1.0.5
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: redis
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -111,8 +111,7 @@ dependencies:
|
|
111
111
|
description: Utilities to be used with PeakFlow.
|
112
112
|
email:
|
113
113
|
- kaspernj@gmail.com
|
114
|
-
executables:
|
115
|
-
- peak_flow_rspec_files
|
114
|
+
executables: []
|
116
115
|
extensions: []
|
117
116
|
extra_rdoc_files: []
|
118
117
|
files:
|
@@ -135,6 +134,7 @@ files:
|
|
135
134
|
- app/services/peak_flow_utils/attribute_service.rb
|
136
135
|
- app/services/peak_flow_utils/configuration_service.rb
|
137
136
|
- app/services/peak_flow_utils/database_initializer_service.rb
|
137
|
+
- app/services/peak_flow_utils/deep_merger.rb
|
138
138
|
- app/services/peak_flow_utils/erb_inspector.rb
|
139
139
|
- app/services/peak_flow_utils/erb_inspector/file_inspector.rb
|
140
140
|
- app/services/peak_flow_utils/erb_inspector/translation_inspector.rb
|
@@ -143,7 +143,6 @@ files:
|
|
143
143
|
- app/services/peak_flow_utils/model_inspector.rb
|
144
144
|
- app/services/peak_flow_utils/translation_service.rb
|
145
145
|
- app/services/peak_flow_utils/translations_parser_service.rb
|
146
|
-
- bin/peak_flow_rspec_files
|
147
146
|
- config/routes.rb
|
148
147
|
- lib/peak_flow_utils.rb
|
149
148
|
- lib/peak_flow_utils/engine.rb
|
@@ -167,7 +166,6 @@ files:
|
|
167
166
|
- lib/peak_flow_utils/notifier_rails.rb
|
168
167
|
- lib/peak_flow_utils/notifier_response.rb
|
169
168
|
- lib/peak_flow_utils/notifier_sidekiq.rb
|
170
|
-
- lib/peak_flow_utils/rspec_helper.rb
|
171
169
|
- lib/peak_flow_utils/version.rb
|
172
170
|
- lib/tasks/peak_flow_utils_tasks.rake
|
173
171
|
homepage: https://github.com/kaspernj/peak_flow_utils
|
@@ -189,7 +187,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
189
187
|
- !ruby/object:Gem::Version
|
190
188
|
version: '0'
|
191
189
|
requirements: []
|
192
|
-
rubygems_version: 3.
|
190
|
+
rubygems_version: 3.2.32
|
193
191
|
signing_key:
|
194
192
|
specification_version: 4
|
195
193
|
summary: Utilities to be used with PeakFlow.
|
data/bin/peak_flow_rspec_files
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
# This task detects and prints out the RSpec files for the current build group
|
4
|
-
|
5
|
-
require "#{__dir__}/../lib/peak_flow_utils"
|
6
|
-
|
7
|
-
args = {}
|
8
|
-
ARGV.each do |arg|
|
9
|
-
if (match = arg.match(/\A--(.+?)=(.+)\Z/))
|
10
|
-
args[match[1]] = match[2]
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
rspec_helper = PeakFlowUtils::RspecHelper.new(
|
15
|
-
groups: args.fetch("groups").to_i,
|
16
|
-
group_number: args.fetch("group-number").to_i,
|
17
|
-
only_types: args["only-types"]&.split(","),
|
18
|
-
tags: args["tags"]&.split(",")
|
19
|
-
)
|
20
|
-
|
21
|
-
print rspec_helper.group_files.map { |group_file| group_file.fetch(:path) }.join(" ")
|
@@ -1,209 +0,0 @@
|
|
1
|
-
class PeakFlowUtils::RspecHelper
|
2
|
-
attr_reader :only_types, :tags
|
3
|
-
|
4
|
-
def initialize(groups:, group_number:, only_types: nil, tags: nil)
|
5
|
-
@groups = groups
|
6
|
-
@group_number = group_number
|
7
|
-
@example_data_exists = File.exist?("spec/examples.txt")
|
8
|
-
@only_types = only_types
|
9
|
-
@tags = tags
|
10
|
-
end
|
11
|
-
|
12
|
-
def example_data_exists?
|
13
|
-
@example_data_exists
|
14
|
-
end
|
15
|
-
|
16
|
-
def example_data
|
17
|
-
@example_data ||= begin
|
18
|
-
raw_data = File.read("spec/examples.txt")
|
19
|
-
|
20
|
-
result = []
|
21
|
-
raw_data.scan(/^\.\/(.+)\[(.+?)\]\s+\|\s+(.+?)\s+\|\s+((.+?) seconds|)\s+\|$/) do |match|
|
22
|
-
file_path = match[0]
|
23
|
-
spec_result = match[1]
|
24
|
-
seconds = match[4]&.to_f
|
25
|
-
|
26
|
-
spec_data = {
|
27
|
-
file_path: file_path,
|
28
|
-
spec_result: spec_result,
|
29
|
-
seconds: seconds
|
30
|
-
}
|
31
|
-
|
32
|
-
result << spec_data
|
33
|
-
end
|
34
|
-
|
35
|
-
result
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
def example_files
|
40
|
-
@example_files ||= begin
|
41
|
-
files = {}
|
42
|
-
example_data.each do |spec_data|
|
43
|
-
file_path = spec_data.fetch(:file_path)
|
44
|
-
seconds = spec_data.fetch(:seconds)
|
45
|
-
|
46
|
-
files[file_path] ||= {examples: 0, seconds: 0.0}
|
47
|
-
files[file_path][:examples] += 1
|
48
|
-
files[file_path][:seconds] += seconds if seconds
|
49
|
-
end
|
50
|
-
|
51
|
-
files
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
def example_file(path)
|
56
|
-
example_files[path]
|
57
|
-
end
|
58
|
-
|
59
|
-
def group_files
|
60
|
-
return @group_files if @group_files
|
61
|
-
|
62
|
-
sorted_files.each do |file|
|
63
|
-
file_path = file.fetch(:path)
|
64
|
-
file_data = example_file(file_path) if example_data_exists?
|
65
|
-
|
66
|
-
if file_data
|
67
|
-
examples = file_data.fetch(:examples)
|
68
|
-
seconds = file_data.fetch(:seconds)
|
69
|
-
else
|
70
|
-
examples = file.fetch(:examples)
|
71
|
-
end
|
72
|
-
|
73
|
-
group = group_with_least
|
74
|
-
group[:examples] += examples
|
75
|
-
group[:files] << file
|
76
|
-
group[:seconds] += seconds if seconds
|
77
|
-
end
|
78
|
-
|
79
|
-
@group_files = group_orders[@group_number - 1].fetch(:files)
|
80
|
-
end
|
81
|
-
|
82
|
-
def group_orders
|
83
|
-
@group_orders ||= begin
|
84
|
-
group_orders = []
|
85
|
-
@groups.times do
|
86
|
-
group_orders << {
|
87
|
-
examples: 0,
|
88
|
-
files: [],
|
89
|
-
seconds: 0.0
|
90
|
-
}
|
91
|
-
end
|
92
|
-
group_orders
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
def group_with_least
|
97
|
-
group_orders.min do |group1, group2|
|
98
|
-
if example_data_exists? && group1.fetch(:seconds) != 0.0 && group2.fetch(:seconds) != 0.0
|
99
|
-
group1.fetch(:seconds) <=> group2.fetch(:seconds)
|
100
|
-
else
|
101
|
-
group1.fetch(:examples) <=> group2.fetch(:examples)
|
102
|
-
end
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
# Sort them so that they are sorted by file path in three groups so each group have an equal amount of controller specs, features specs and so on
|
107
|
-
def sorted_files
|
108
|
-
files.values.sort do |file1, file2|
|
109
|
-
file1_path = file1.fetch(:path)
|
110
|
-
file2_path = file2.fetch(:path)
|
111
|
-
|
112
|
-
file1_data = example_file(file1_path) if example_data_exists?
|
113
|
-
file2_data = example_file(file2_path) if example_data_exists?
|
114
|
-
|
115
|
-
if file1_data && file2_data && file1_data.fetch(:seconds) != 0.0 && file2_data.fetch(:seconds) != 0.0
|
116
|
-
value1 = file1_data[:seconds]
|
117
|
-
else
|
118
|
-
value1 = file1.fetch(:points)
|
119
|
-
end
|
120
|
-
|
121
|
-
if file2_data && file1_data && file2_data.fetch(:seconds) != 0.0 && file2_data.fetch(:seconds) != 0.0
|
122
|
-
value2 = file2_data[:seconds]
|
123
|
-
else
|
124
|
-
value2 = file2.fetch(:points)
|
125
|
-
end
|
126
|
-
|
127
|
-
if value1 == value2
|
128
|
-
value2 = file1_path
|
129
|
-
value1 = file2_path
|
130
|
-
end
|
131
|
-
|
132
|
-
value2 <=> value1
|
133
|
-
end
|
134
|
-
end
|
135
|
-
|
136
|
-
private
|
137
|
-
|
138
|
-
def dry_result
|
139
|
-
@dry_result ||= begin
|
140
|
-
require "json"
|
141
|
-
require "rspec/core"
|
142
|
-
|
143
|
-
output_capture = StringIO.new
|
144
|
-
RSpec::Core::Runner.run(rspec_options, $stderr, output_capture)
|
145
|
-
|
146
|
-
result = ::JSON.parse(output_capture.string)
|
147
|
-
|
148
|
-
raise "No examples were found" if result.fetch("examples").empty?
|
149
|
-
|
150
|
-
result
|
151
|
-
end
|
152
|
-
end
|
153
|
-
|
154
|
-
def dry_file(path)
|
155
|
-
files.fetch(path)
|
156
|
-
end
|
157
|
-
|
158
|
-
def files
|
159
|
-
@files ||= begin
|
160
|
-
result = {}
|
161
|
-
dry_result.fetch("examples").each do |example|
|
162
|
-
file_path = example.fetch("file_path")
|
163
|
-
file_path = file_path[2, file_path.length]
|
164
|
-
type = type_from_path(file_path)
|
165
|
-
points = points_from_type(type)
|
166
|
-
|
167
|
-
next if ignore_type?(type)
|
168
|
-
|
169
|
-
result[file_path] = {examples: 0, path: file_path, points: 0, type: type} unless result.key?(file_path)
|
170
|
-
result[file_path][:examples] += 1
|
171
|
-
result[file_path][:points] += points
|
172
|
-
end
|
173
|
-
|
174
|
-
result
|
175
|
-
end
|
176
|
-
end
|
177
|
-
|
178
|
-
def ignore_type?(type)
|
179
|
-
only_types && !only_types.include?(type) # rubocop:disable Rails/NegateInclude:, Style/SafeNavigation
|
180
|
-
end
|
181
|
-
|
182
|
-
def points_from_type(type)
|
183
|
-
if type == "feature" || type == "system"
|
184
|
-
10
|
185
|
-
elsif type == "controllers"
|
186
|
-
3
|
187
|
-
else
|
188
|
-
1
|
189
|
-
end
|
190
|
-
end
|
191
|
-
|
192
|
-
def rspec_options
|
193
|
-
rspec_options = ["--dry-run", "--format", "json"]
|
194
|
-
|
195
|
-
tags&.each do |tag|
|
196
|
-
rspec_options += ["--tag", tag]
|
197
|
-
end
|
198
|
-
|
199
|
-
# Add the folder with all the specs, which is required when running programmatically
|
200
|
-
rspec_options << "spec"
|
201
|
-
|
202
|
-
rspec_options
|
203
|
-
end
|
204
|
-
|
205
|
-
def type_from_path(file_path)
|
206
|
-
match = file_path.match(/^spec\/(.+?)\//)
|
207
|
-
match[1] if match
|
208
|
-
end
|
209
|
-
end
|