diffend 0.2.18 → 0.2.26
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 +14 -2
- data/CHANGELOG.md +47 -1
- data/Gemfile +2 -1
- data/Gemfile.lock +12 -1
- data/{LICENSE → LICENSE.md} +0 -0
- data/lib/diffend.rb +86 -19
- data/lib/diffend/build_bundler_definition.rb +26 -0
- data/lib/diffend/errors.rb +2 -4
- 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 +29 -0
- data/lib/diffend/handle_errors/report.rb +59 -0
- data/lib/diffend/request.rb +165 -0
- data/lib/diffend/voting.rb +71 -12
- data/lib/diffend/voting/versions/local.rb +156 -52
- data/lib/diffend/voting/versions/remote.rb +46 -14
- data/scripts/generate_payload_for_file.rb +1 -1
- metadata +9 -4
- metadata.gz.sig +0 -0
- data/lib/diffend/voting/request.rb +0 -191
|
@@ -20,14 +20,25 @@ module Diffend
|
|
|
20
20
|
class << self
|
|
21
21
|
# @param command [String] either install or update
|
|
22
22
|
# @param definition [Bundler::Definition] definition for your source
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
# @param config [OpenStruct] diffend config
|
|
24
|
+
def call(command, config, definition)
|
|
25
|
+
payload = payload(command, config.project_id, definition)
|
|
26
|
+
|
|
27
|
+
response = Diffend::Request.call(
|
|
28
|
+
config,
|
|
29
|
+
commands_url(command, config.project_id),
|
|
30
|
+
payload
|
|
28
31
|
)
|
|
29
32
|
|
|
30
33
|
JSON.parse(response.body)
|
|
34
|
+
rescue StandardError => e
|
|
35
|
+
Diffend::HandleErrors::Report.call(
|
|
36
|
+
exception: e,
|
|
37
|
+
payload: payload || {},
|
|
38
|
+
config: config,
|
|
39
|
+
message: :unhandled_exception,
|
|
40
|
+
report: true
|
|
41
|
+
)
|
|
31
42
|
end
|
|
32
43
|
|
|
33
44
|
# Build diffend, host, packages, and platform specific information
|
|
@@ -85,6 +96,9 @@ module Diffend
|
|
|
85
96
|
}.freeze
|
|
86
97
|
end
|
|
87
98
|
|
|
99
|
+
# Build platform ruby information
|
|
100
|
+
#
|
|
101
|
+
# @return [Hash]
|
|
88
102
|
def build_platform_ruby
|
|
89
103
|
if defined?(JRUBY_VERSION)
|
|
90
104
|
revision = JRUBY_REVISION.to_s
|
|
@@ -117,7 +131,7 @@ module Diffend
|
|
|
117
131
|
uname = Etc.uname
|
|
118
132
|
|
|
119
133
|
{
|
|
120
|
-
'command' =>
|
|
134
|
+
'command' => build_host_command,
|
|
121
135
|
'ips' => build_host_ips,
|
|
122
136
|
'name' => uname[:nodename],
|
|
123
137
|
'system' => {
|
|
@@ -127,10 +141,24 @@ module Diffend
|
|
|
127
141
|
'version' => uname[:version]
|
|
128
142
|
},
|
|
129
143
|
'tags' => build_host_tags,
|
|
130
|
-
'user' => Etc.getpwuid(Process.uid).name
|
|
144
|
+
'user' => Etc.getpwuid(Process.uid).name,
|
|
145
|
+
'pid' => Process.pid
|
|
131
146
|
}.freeze
|
|
132
147
|
end
|
|
133
148
|
|
|
149
|
+
# Build host command information
|
|
150
|
+
#
|
|
151
|
+
# @return [Hash]
|
|
152
|
+
def build_host_command
|
|
153
|
+
{
|
|
154
|
+
'name' => $PROGRAM_NAME.split('/').last.strip,
|
|
155
|
+
'options' => ARGV.join(' ')
|
|
156
|
+
}
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
# Build host ips, except localhost and loopback
|
|
160
|
+
#
|
|
161
|
+
# @return [Array<String>]
|
|
134
162
|
def build_host_ips
|
|
135
163
|
Socket.ip_address_list.map do |ip|
|
|
136
164
|
next if ip.ipv4_loopback? || ip.ipv6_loopback? || ip.ipv6_linklocal?
|
|
@@ -139,6 +167,9 @@ module Diffend
|
|
|
139
167
|
end.compact
|
|
140
168
|
end
|
|
141
169
|
|
|
170
|
+
# Build host tags
|
|
171
|
+
#
|
|
172
|
+
# @return [Array]
|
|
142
173
|
def build_host_tags
|
|
143
174
|
tags = []
|
|
144
175
|
|
|
@@ -155,15 +186,16 @@ module Diffend
|
|
|
155
186
|
tags
|
|
156
187
|
end
|
|
157
188
|
|
|
158
|
-
#
|
|
189
|
+
# Provides diffend command endpoint url
|
|
159
190
|
#
|
|
160
|
-
# @
|
|
191
|
+
# @param command [String] either install or update
|
|
192
|
+
# @param project_id [String] diffend project_id
|
|
161
193
|
#
|
|
162
|
-
# @
|
|
163
|
-
def
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
194
|
+
# @return [String] diffend endpoint
|
|
195
|
+
def commands_url(command, project_id)
|
|
196
|
+
return ENV['DIFFEND_COMMAND_URL'] if ENV.key?('DIFFEND_COMMAND_URL')
|
|
197
|
+
|
|
198
|
+
"https://my.diffend.io/api/projects/#{project_id}/bundle/#{command}"
|
|
167
199
|
end
|
|
168
200
|
end
|
|
169
201
|
end
|
|
@@ -10,6 +10,6 @@ project_id = nil
|
|
|
10
10
|
gemfile = ARGV[0]
|
|
11
11
|
lockfile = ARGV[1]
|
|
12
12
|
|
|
13
|
-
definition =
|
|
13
|
+
definition = Diffend::BuildBundlerDefinition.call(command, gemfile lockfile)
|
|
14
14
|
|
|
15
15
|
pp Diffend::Voting::Versions::Remote.payload(command, project_id, definition)
|
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.26
|
|
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-10 00:00:00.000000000 Z
|
|
38
38
|
dependencies:
|
|
39
39
|
- !ruby/object:Gem::Dependency
|
|
40
40
|
name: bundler
|
|
@@ -80,7 +80,7 @@ files:
|
|
|
80
80
|
- CHANGELOG.md
|
|
81
81
|
- Gemfile
|
|
82
82
|
- Gemfile.lock
|
|
83
|
-
- LICENSE
|
|
83
|
+
- LICENSE.md
|
|
84
84
|
- README.md
|
|
85
85
|
- bin/bundle
|
|
86
86
|
- bin/byebug
|
|
@@ -92,13 +92,18 @@ files:
|
|
|
92
92
|
- certs/tomaszpajor.pem
|
|
93
93
|
- diffend.gemspec
|
|
94
94
|
- lib/diffend.rb
|
|
95
|
+
- lib/diffend/build_bundler_definition.rb
|
|
95
96
|
- lib/diffend/commands.rb
|
|
96
97
|
- lib/diffend/config/fetcher.rb
|
|
97
98
|
- lib/diffend/config/file_finder.rb
|
|
98
99
|
- lib/diffend/config/validator.rb
|
|
99
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
|
|
100
106
|
- lib/diffend/voting.rb
|
|
101
|
-
- lib/diffend/voting/request.rb
|
|
102
107
|
- lib/diffend/voting/versions/local.rb
|
|
103
108
|
- lib/diffend/voting/versions/remote.rb
|
|
104
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
|