peak_flow_utils 0.1.14 → 0.1.15

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7e3d80778a6e2f090ed1247e8afd8b0cf95c1c57d96a01315534f32aa0a56d00
4
- data.tar.gz: b4ab6fd0ba591e3f750dca4d1fea08de84d2d04a150b0bf6a8a90c15928b4157
3
+ metadata.gz: b4fb7a276f751a58ba19b74e73955323e0f1b89215312b50ee3e3b9cf89a85f4
4
+ data.tar.gz: 29edd9b2f4225cf2ea74c67d4fccd1b21a0149781f2cacc168309ef8dd3082c6
5
5
  SHA512:
6
- metadata.gz: 9dc474ec28b8221fb5730bad562121ef0925e6bb2cd0f554e759d51a5daba2169bb0290253b10dfda1a140a616c21751f228c2994bcddf468c6a5bae3b7d741a
7
- data.tar.gz: 57b9245ce4892aa877dd01b7947f9db2a19a80cb1355a2a6ab57350779cd3c9090567417bd369399d8a4daba65c00d867c76fdb506b85e5342a330c3e79414bd
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.notify(*args)
18
- PeakFlowUtils::Notifier.current.notify(*args)
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: 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.notify(
15
- environment: env,
16
- error: e,
17
- parameters: parameters
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
@@ -1,3 +1,3 @@
1
1
  module PeakFlowUtils
2
- VERSION = "0.1.14".freeze
2
+ VERSION = "0.1.15".freeze
3
3
  end
@@ -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.14
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: 2021-10-04 00:00:00.000000000 Z
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.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.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.1.6
190
+ rubygems_version: 3.2.32
193
191
  signing_key:
194
192
  specification_version: 4
195
193
  summary: Utilities to be used with PeakFlow.
@@ -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