diffend 0.2.16 → 0.2.23
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.tar.gz.sig +0 -0
- data/.github/workflows/ci.yml +12 -2
- data/CHANGELOG.md +48 -0
- data/Gemfile +2 -1
- data/Gemfile.lock +12 -1
- data/{LICENSE → LICENSE.md} +0 -0
- data/lib/diffend.rb +39 -21
- data/lib/diffend/build_bundler_definition.rb +26 -0
- data/lib/diffend/config/fetcher.rb +92 -9
- data/lib/diffend/config/validator.rb +25 -0
- data/lib/diffend/errors.rb +12 -0
- data/lib/diffend/handle_errors/build_exception_payload.rb +30 -0
- data/lib/diffend/handle_errors/display_to_stdout.rb +17 -0
- data/lib/diffend/handle_errors/messages.rb +19 -0
- data/lib/diffend/handle_errors/report.rb +59 -0
- data/lib/diffend/request.rb +139 -0
- data/lib/diffend/voting/versions/local.rb +144 -49
- data/lib/diffend/voting/versions/remote.rb +49 -7
- metadata +11 -4
- metadata.gz.sig +0 -0
- data/lib/diffend/voting/request.rb +0 -191
|
@@ -23,11 +23,23 @@ module Diffend
|
|
|
23
23
|
def call(command, definition)
|
|
24
24
|
config = fetch_config
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
payload = payload(command, config.project_id, definition)
|
|
27
|
+
|
|
28
|
+
response = Diffend::Request.call(
|
|
29
|
+
config,
|
|
30
|
+
commands_url(command, config.project_id),
|
|
31
|
+
payload
|
|
28
32
|
)
|
|
29
33
|
|
|
30
34
|
JSON.parse(response.body)
|
|
35
|
+
rescue StandardError => e
|
|
36
|
+
Diffend::HandleErrors::Report.call(
|
|
37
|
+
exception: e,
|
|
38
|
+
payload: payload,
|
|
39
|
+
config: config,
|
|
40
|
+
message: :unhandled_exception,
|
|
41
|
+
report: true
|
|
42
|
+
)
|
|
31
43
|
end
|
|
32
44
|
|
|
33
45
|
# Build diffend, host, packages, and platform specific information
|
|
@@ -85,6 +97,9 @@ module Diffend
|
|
|
85
97
|
}.freeze
|
|
86
98
|
end
|
|
87
99
|
|
|
100
|
+
# Build platform ruby information
|
|
101
|
+
#
|
|
102
|
+
# @return [Hash]
|
|
88
103
|
def build_platform_ruby
|
|
89
104
|
if defined?(JRUBY_VERSION)
|
|
90
105
|
revision = JRUBY_REVISION.to_s
|
|
@@ -117,7 +132,7 @@ module Diffend
|
|
|
117
132
|
uname = Etc.uname
|
|
118
133
|
|
|
119
134
|
{
|
|
120
|
-
'command' =>
|
|
135
|
+
'command' => build_host_command,
|
|
121
136
|
'ips' => build_host_ips,
|
|
122
137
|
'name' => uname[:nodename],
|
|
123
138
|
'system' => {
|
|
@@ -127,10 +142,24 @@ module Diffend
|
|
|
127
142
|
'version' => uname[:version]
|
|
128
143
|
},
|
|
129
144
|
'tags' => build_host_tags,
|
|
130
|
-
'user' => Etc.
|
|
145
|
+
'user' => Etc.getpwuid(Process.uid).name,
|
|
146
|
+
'pid' => Process.pid
|
|
131
147
|
}.freeze
|
|
132
148
|
end
|
|
133
149
|
|
|
150
|
+
# Build host command information
|
|
151
|
+
#
|
|
152
|
+
# @return [Hash]
|
|
153
|
+
def build_host_command
|
|
154
|
+
{
|
|
155
|
+
'name' => $PROGRAM_NAME.split('/').last.strip,
|
|
156
|
+
'options' => ARGV.join(' ')
|
|
157
|
+
}
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
# Build host ips, except localhost and loopback
|
|
161
|
+
#
|
|
162
|
+
# @return [Array<String>]
|
|
134
163
|
def build_host_ips
|
|
135
164
|
Socket.ip_address_list.map do |ip|
|
|
136
165
|
next if ip.ipv4_loopback? || ip.ipv6_loopback? || ip.ipv6_linklocal?
|
|
@@ -139,6 +168,9 @@ module Diffend
|
|
|
139
168
|
end.compact
|
|
140
169
|
end
|
|
141
170
|
|
|
171
|
+
# Build host tags
|
|
172
|
+
#
|
|
173
|
+
# @return [Array]
|
|
142
174
|
def build_host_tags
|
|
143
175
|
tags = []
|
|
144
176
|
|
|
@@ -155,7 +187,7 @@ module Diffend
|
|
|
155
187
|
tags
|
|
156
188
|
end
|
|
157
189
|
|
|
158
|
-
# Fetch
|
|
190
|
+
# Fetch diffend config file
|
|
159
191
|
#
|
|
160
192
|
# @return [OpenStruct, nil] configuration object
|
|
161
193
|
#
|
|
@@ -164,8 +196,18 @@ module Diffend
|
|
|
164
196
|
Config::Fetcher.call(
|
|
165
197
|
File.expand_path('..', Bundler.bin_path)
|
|
166
198
|
)
|
|
167
|
-
|
|
168
|
-
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
# Provides diffend command endpoint url
|
|
202
|
+
#
|
|
203
|
+
# @param command [String] either install or update
|
|
204
|
+
# @param project_id [String] diffend project_id
|
|
205
|
+
#
|
|
206
|
+
# @return [String] diffend endpoint
|
|
207
|
+
def commands_url(command, project_id)
|
|
208
|
+
return ENV['DIFFEND_COMMAND_URL'] if ENV.key?('DIFFEND_COMMAND_URL')
|
|
209
|
+
|
|
210
|
+
"https://my.diffend.io/api/projects/#{project_id}/bundle/#{command}"
|
|
169
211
|
end
|
|
170
212
|
end
|
|
171
213
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: diffend
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.23
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Tomasz Pajor
|
|
@@ -34,7 +34,7 @@ cert_chain:
|
|
|
34
34
|
9MmF6uCQa1EjK2p8tYT0MnbHrFkoehxdX4VO9y99GAkhZyJNKPYPtyAUFV27sT2V
|
|
35
35
|
LfCJRk4ifKIN/FUCwDSn8Cz0m6oH265q0p6wdzI6qrWOjP8tGOMBTA==
|
|
36
36
|
-----END CERTIFICATE-----
|
|
37
|
-
date: 2020-
|
|
37
|
+
date: 2020-09-06 00:00:00.000000000 Z
|
|
38
38
|
dependencies:
|
|
39
39
|
- !ruby/object:Gem::Dependency
|
|
40
40
|
name: bundler
|
|
@@ -77,9 +77,10 @@ files:
|
|
|
77
77
|
- ".gitignore"
|
|
78
78
|
- ".rspec"
|
|
79
79
|
- ".ruby-version"
|
|
80
|
+
- CHANGELOG.md
|
|
80
81
|
- Gemfile
|
|
81
82
|
- Gemfile.lock
|
|
82
|
-
- LICENSE
|
|
83
|
+
- LICENSE.md
|
|
83
84
|
- README.md
|
|
84
85
|
- bin/bundle
|
|
85
86
|
- bin/byebug
|
|
@@ -91,12 +92,18 @@ files:
|
|
|
91
92
|
- certs/tomaszpajor.pem
|
|
92
93
|
- diffend.gemspec
|
|
93
94
|
- lib/diffend.rb
|
|
95
|
+
- lib/diffend/build_bundler_definition.rb
|
|
94
96
|
- lib/diffend/commands.rb
|
|
95
97
|
- lib/diffend/config/fetcher.rb
|
|
96
98
|
- lib/diffend/config/file_finder.rb
|
|
99
|
+
- lib/diffend/config/validator.rb
|
|
97
100
|
- lib/diffend/errors.rb
|
|
101
|
+
- lib/diffend/handle_errors/build_exception_payload.rb
|
|
102
|
+
- lib/diffend/handle_errors/display_to_stdout.rb
|
|
103
|
+
- lib/diffend/handle_errors/messages.rb
|
|
104
|
+
- lib/diffend/handle_errors/report.rb
|
|
105
|
+
- lib/diffend/request.rb
|
|
98
106
|
- lib/diffend/voting.rb
|
|
99
|
-
- lib/diffend/voting/request.rb
|
|
100
107
|
- lib/diffend/voting/versions/local.rb
|
|
101
108
|
- lib/diffend/voting/versions/remote.rb
|
|
102
109
|
- plugins.rb
|
metadata.gz.sig
CHANGED
|
Binary file
|
|
@@ -1,191 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'net/http'
|
|
4
|
-
require 'openssl'
|
|
5
|
-
require 'json'
|
|
6
|
-
require 'securerandom'
|
|
7
|
-
|
|
8
|
-
module Diffend
|
|
9
|
-
module Voting
|
|
10
|
-
# Module responsible for doing request to Diffend
|
|
11
|
-
module Request
|
|
12
|
-
# List of connection exceptions
|
|
13
|
-
CONNECTION_EXCEPTIONS = [
|
|
14
|
-
Errno::ECONNRESET,
|
|
15
|
-
Errno::ENETUNREACH,
|
|
16
|
-
Errno::EHOSTUNREACH,
|
|
17
|
-
Errno::ECONNREFUSED
|
|
18
|
-
].freeze
|
|
19
|
-
# List of timeout exceptions
|
|
20
|
-
TIMEOUT_EXCEPTIONS = [
|
|
21
|
-
Net::OpenTimeout,
|
|
22
|
-
Net::ReadTimeout
|
|
23
|
-
].freeze
|
|
24
|
-
# Request headers
|
|
25
|
-
HEADERS = { 'Content-Type': 'application/json' }.freeze
|
|
26
|
-
|
|
27
|
-
private_constant :HEADERS
|
|
28
|
-
|
|
29
|
-
class << self
|
|
30
|
-
# Execute request to Diffend
|
|
31
|
-
#
|
|
32
|
-
# @param command [String] either install or update
|
|
33
|
-
# @param payload [Hash] with versions to check
|
|
34
|
-
# @param config [OpenStruct] Diffend config
|
|
35
|
-
#
|
|
36
|
-
# @return [Net::HTTPResponse] response from Diffend
|
|
37
|
-
def call(command, payload, config)
|
|
38
|
-
retry_count ||= 0
|
|
39
|
-
|
|
40
|
-
build_http(commands_url(command, config.project_id)) do |http, uri|
|
|
41
|
-
http.request(build_request(uri, config, payload))
|
|
42
|
-
end
|
|
43
|
-
rescue *CONNECTION_EXCEPTIONS => e
|
|
44
|
-
Bundler.ui.error('We experienced a connection issue, retrying...')
|
|
45
|
-
sleep(exponential_backoff(retry_count))
|
|
46
|
-
retry_count += 1
|
|
47
|
-
|
|
48
|
-
retry if retry_count < 3
|
|
49
|
-
|
|
50
|
-
output_report(build_report(payload, e))
|
|
51
|
-
Bundler.ui.error('^^^ Above is the dump of your request ^^^')
|
|
52
|
-
Bundler.ui.error(build_request_error_message)
|
|
53
|
-
|
|
54
|
-
exit 1
|
|
55
|
-
rescue *TIMEOUT_EXCEPTIONS => e
|
|
56
|
-
Bundler.ui.error('We experienced a timeout issue, retrying...')
|
|
57
|
-
sleep(exponential_backoff(retry_count))
|
|
58
|
-
retry_count += 1
|
|
59
|
-
|
|
60
|
-
retry if retry_count < 3
|
|
61
|
-
|
|
62
|
-
output_report(build_report(payload, e))
|
|
63
|
-
Bundler.ui.error('^^^ Above is the dump of your request ^^^')
|
|
64
|
-
Bundler.ui.error(build_request_error_message)
|
|
65
|
-
|
|
66
|
-
exit 1
|
|
67
|
-
rescue StandardError => e
|
|
68
|
-
exception_payload = build_report(payload, e)
|
|
69
|
-
output_report(exception_payload)
|
|
70
|
-
Bundler.ui.error('^^^ Above is the dump of your request ^^^')
|
|
71
|
-
Bundler.ui.error(build_unhandled_exception_message)
|
|
72
|
-
|
|
73
|
-
build_http(errors_url(config.project_id)) do |http, uri|
|
|
74
|
-
http.request(build_request(uri, config, exception_payload))
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
exit 1
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
# Builds http connection object
|
|
81
|
-
#
|
|
82
|
-
# @param url [String] command endpoint url
|
|
83
|
-
def build_http(url)
|
|
84
|
-
uri = URI(url)
|
|
85
|
-
|
|
86
|
-
Net::HTTP.start(
|
|
87
|
-
uri.host,
|
|
88
|
-
uri.port,
|
|
89
|
-
use_ssl: uri.scheme == 'https',
|
|
90
|
-
verify_mode: OpenSSL::SSL::VERIFY_NONE,
|
|
91
|
-
open_timeout: 5,
|
|
92
|
-
read_timeout: 5
|
|
93
|
-
) { |http| yield(http, uri) }
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
# Build http post request and assigns headers and payload
|
|
97
|
-
#
|
|
98
|
-
# @param uri [URI::HTTPS]
|
|
99
|
-
# @param config [OpenStruct] Diffend config
|
|
100
|
-
# @param payload [Hash] with versions to check
|
|
101
|
-
#
|
|
102
|
-
# @return [Net::HTTP::Post]
|
|
103
|
-
def build_request(uri, config, payload)
|
|
104
|
-
Net::HTTP::Post
|
|
105
|
-
.new(uri.request_uri, HEADERS)
|
|
106
|
-
.tap { |request| assign_auth(request, config) }
|
|
107
|
-
.tap { |request| assign_payload(request, payload) }
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
# Assigns basic authorization if provided in the config
|
|
111
|
-
#
|
|
112
|
-
# @param request [Net::HTTP::Post] prepared http post
|
|
113
|
-
# @param config [OpenStruct] Diffend config
|
|
114
|
-
def assign_auth(request, config)
|
|
115
|
-
return unless config
|
|
116
|
-
return unless config.shareable_id
|
|
117
|
-
return unless config.shareable_key
|
|
118
|
-
|
|
119
|
-
request.basic_auth(config.shareable_id, config.shareable_key)
|
|
120
|
-
end
|
|
121
|
-
|
|
122
|
-
# Assigns payload as json
|
|
123
|
-
#
|
|
124
|
-
# @param request [Net::HTTP::Post] prepared http post
|
|
125
|
-
# @param payload [Hash] with versions to check
|
|
126
|
-
def assign_payload(request, payload)
|
|
127
|
-
request.body = JSON.dump(payload: payload)
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
# Provides diffend command endpoint url
|
|
131
|
-
#
|
|
132
|
-
# @param command [String] either install or update
|
|
133
|
-
# @param project_id [String] diffend project_id
|
|
134
|
-
#
|
|
135
|
-
# @return [String] diffend endpoint
|
|
136
|
-
def commands_url(command, project_id)
|
|
137
|
-
return ENV['DIFFEND_COMMAND_URL'] if ENV.key?('DIFFEND_COMMAND_URL')
|
|
138
|
-
|
|
139
|
-
"https://my.diffend.io/api/projects/#{project_id}/bundle/#{command}"
|
|
140
|
-
end
|
|
141
|
-
|
|
142
|
-
# Provides diffend errors endpoint url
|
|
143
|
-
#
|
|
144
|
-
# @param project_id [String] diffend project_id
|
|
145
|
-
#
|
|
146
|
-
# @return [String] diffend endpoint
|
|
147
|
-
def errors_url(project_id)
|
|
148
|
-
return ENV['DIFFEND_ERROR_URL'] if ENV.key?('DIFFEND_ERROR_URL')
|
|
149
|
-
|
|
150
|
-
"https://my.diffend.io/api/projects/#{project_id}/errors"
|
|
151
|
-
end
|
|
152
|
-
|
|
153
|
-
def exponential_backoff(retry_count)
|
|
154
|
-
2**(retry_count + 1)
|
|
155
|
-
end
|
|
156
|
-
|
|
157
|
-
def build_request_error_message
|
|
158
|
-
<<~MSG
|
|
159
|
-
\nWe were unable to process your request at this time. We recorded this incident in our system and will review it.\n
|
|
160
|
-
If you think that this is a bug, don't hesitate.\n
|
|
161
|
-
Create an issue on https://github.com/diffend-io/diffend-ruby/issues\n
|
|
162
|
-
MSG
|
|
163
|
-
end
|
|
164
|
-
|
|
165
|
-
def build_unhandled_exception_message
|
|
166
|
-
<<~MSG
|
|
167
|
-
\nSomething went really wrong. We recorded this incident in our system and will review it.\n
|
|
168
|
-
This is a bug, don't hesitate.\n
|
|
169
|
-
Create an issue on https://github.com/diffend-io/diffend-ruby/issues\n
|
|
170
|
-
MSG
|
|
171
|
-
end
|
|
172
|
-
|
|
173
|
-
def build_report(payload, exception)
|
|
174
|
-
{
|
|
175
|
-
request_id: SecureRandom.uuid,
|
|
176
|
-
payload: payload,
|
|
177
|
-
exception: {
|
|
178
|
-
class: exception.class,
|
|
179
|
-
message: exception.message,
|
|
180
|
-
backtrace: exception.backtrace
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
end
|
|
184
|
-
|
|
185
|
-
def output_report(report)
|
|
186
|
-
puts report.to_json
|
|
187
|
-
end
|
|
188
|
-
end
|
|
189
|
-
end
|
|
190
|
-
end
|
|
191
|
-
end
|