diffend 0.2.23 → 0.2.28
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/.github/workflows/ci.yml +2 -0
- data/CHANGELOG.md +33 -1
- data/Gemfile.lock +1 -1
- data/lib/diffend.rb +63 -2
- data/lib/diffend/commands.rb +4 -2
- data/lib/diffend/config/fetcher.rb +8 -4
- data/lib/diffend/errors.rb +4 -4
- data/lib/diffend/handle_errors/build_exception_payload.rb +4 -4
- data/lib/diffend/handle_errors/messages.rb +10 -0
- data/lib/diffend/handle_errors/report.rb +17 -5
- data/lib/diffend/monitor.rb +30 -0
- data/lib/diffend/request.rb +59 -13
- data/lib/diffend/request_object.rb +6 -0
- data/lib/diffend/track.rb +104 -0
- data/lib/diffend/voting.rb +72 -13
- data/lib/diffend/voting/versions/local.rb +28 -19
- data/lib/diffend/voting/versions/remote.rb +28 -22
- data/scripts/generate_payload_for_file.rb +1 -1
- metadata +5 -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: 0c100adca589f5e4e22488ecc8d12a865b2ec8a5bb6be4bf15f3b4bf5d5ad089
|
4
|
+
data.tar.gz: 8e5820badb850ee24606874e8de80a8e19114a08276f9fca3933a54e4fb825bc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 70b2798f074676511abc75974db24ee116dcbf9fc87983a4cfc6d9e69246c12b0970c376ced03e08a6fb0a9ba09fa9cd11a3da5d728715c6ec676030bd7ebccd
|
7
|
+
data.tar.gz: fd130a1283b65d6487bab7323eb2a7d7c9d3db6cea7c777e4c7a023f77e9b0d0ee4078cd38c9228fe18b1555ee9e9ec9efd0fa1033a7c8ed5e19859cb8e11970
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/.github/workflows/ci.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,32 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
3
|
## [Unreleased][master]
|
4
|
+
|
5
|
+
## [0.2.28] (2020-09-19)
|
6
|
+
- start `Diffend::Monitor` only if not in development or test ([#44](https://github.com/diffend-io/diffend-ruby/pull/44))
|
7
|
+
- better host command expose ([#45](https://github.com/diffend-io/diffend-ruby/pull/45))
|
8
|
+
|
9
|
+
## [0.2.27] (2020-09-16)
|
10
|
+
- introduce `Diffend::RequestObject` ([#40](https://github.com/diffend-io/diffend-ruby/pull/40))
|
11
|
+
- clean up error codes and introduce `DIFFEND_INGORE_EXCEPTIONS` ([#41](https://github.com/diffend-io/diffend-ruby/pull/41))
|
12
|
+
- introduce `Diffend::Monitor` and `Diffend::Track` ([#15](https://github.com/diffend-io/diffend-ruby/pull/15))
|
13
|
+
|
14
|
+
## [0.2.26] (2020-09-10)
|
15
|
+
- introduce `DIFFEND_DEVELOPMENT` environment variable ([#36](https://github.com/diffend-io/diffend-ruby/pull/36))
|
16
|
+
- adjust message for allow verdict ([#37](https://github.com/diffend-io/diffend-ruby/pull/37))
|
17
|
+
- do not run the plugin when it is not enabled ([#38](https://github.com/diffend-io/diffend-ruby/pull/38))
|
18
|
+
|
19
|
+
## [0.2.25] (2020-09-09)
|
20
|
+
- add support for a warn verdict ([#34](https://github.com/diffend-io/diffend-ruby/pull/34))
|
21
|
+
|
22
|
+
## [0.2.24] (2020-09-08)
|
23
|
+
- better error handling of response ([#28](https://github.com/diffend-io/diffend-ruby/pull/28))
|
24
|
+
- fix jruby specs ([#29](https://github.com/diffend-io/diffend-ruby/pull/29))
|
25
|
+
- handle request server errors ([#30](https://github.com/diffend-io/diffend-ruby/pull/30))
|
26
|
+
- better detection of gem source ([#31](https://github.com/diffend-io/diffend-ruby/pull/31))
|
27
|
+
- detect if we are running outdated version of the plugin ([#32](https://github.com/diffend-io/diffend-ruby/pull/32))
|
28
|
+
|
29
|
+
## [0.2.23] (2020-09-06)
|
4
30
|
- fix how we build gem platform ([#26](https://github.com/diffend-io/diffend-ruby/pull/26))
|
5
31
|
- test against jruby, ruby-2.5 and ruby-2.6 ([#25](https://github.com/diffend-io/diffend-ruby/pull/25))
|
6
32
|
|
@@ -38,7 +64,13 @@
|
|
38
64
|
|
39
65
|
- initial release
|
40
66
|
|
41
|
-
[master]: https://github.com/diffend-io/diffend-ruby/compare/v0.2.
|
67
|
+
[master]: https://github.com/diffend-io/diffend-ruby/compare/v0.2.28...HEAD
|
68
|
+
[0.2.28]: https://github.com/diffend-io/diffend-ruby/compare/v0.2.27...v0.2.28
|
69
|
+
[0.2.27]: https://github.com/diffend-io/diffend-ruby/compare/v0.2.26...v0.2.27
|
70
|
+
[0.2.26]: https://github.com/diffend-io/diffend-ruby/compare/v0.2.25...v0.2.26
|
71
|
+
[0.2.25]: https://github.com/diffend-io/diffend-ruby/compare/v0.2.24...v0.2.25
|
72
|
+
[0.2.24]: https://github.com/diffend-io/diffend-ruby/compare/v0.2.23...v0.2.24
|
73
|
+
[0.2.23]: https://github.com/diffend-io/diffend-ruby/compare/v0.2.22...v0.2.23
|
42
74
|
[0.2.22]: https://github.com/diffend-io/diffend-ruby/compare/v0.2.21...v0.2.22
|
43
75
|
[0.2.21]: https://github.com/diffend-io/diffend-ruby/compare/v0.2.20...v0.2.21
|
44
76
|
[0.2.20]: https://github.com/diffend-io/diffend-ruby/compare/v0.2.19...v0.2.20
|
data/Gemfile.lock
CHANGED
data/lib/diffend.rb
CHANGED
@@ -15,8 +15,10 @@
|
|
15
15
|
handle_errors/build_exception_payload
|
16
16
|
handle_errors/display_to_stdout
|
17
17
|
handle_errors/report
|
18
|
+
request_object
|
18
19
|
request
|
19
20
|
voting
|
21
|
+
track
|
20
22
|
].each { |file| require "diffend/#{file}" }
|
21
23
|
|
22
24
|
%w[
|
@@ -27,7 +29,7 @@
|
|
27
29
|
# Diffend main namespace
|
28
30
|
module Diffend
|
29
31
|
# Current plugin version
|
30
|
-
VERSION = '0.2.
|
32
|
+
VERSION = '0.2.28'
|
31
33
|
# Diffend homepage
|
32
34
|
HOMEPAGE = 'https://diffend.io'
|
33
35
|
|
@@ -41,23 +43,82 @@ module Diffend
|
|
41
43
|
|
42
44
|
# Execute diffend plugin
|
43
45
|
def execute
|
46
|
+
return unless enabled?
|
47
|
+
|
48
|
+
verify_version
|
49
|
+
|
44
50
|
config = fetch_config
|
45
51
|
|
46
52
|
Diffend::Voting.call(
|
47
53
|
command,
|
54
|
+
config,
|
48
55
|
Diffend::BuildBundlerDefinition.call(
|
49
56
|
command,
|
50
57
|
Bundler.default_gemfile,
|
51
58
|
Bundler.default_lockfile
|
52
59
|
)
|
53
60
|
)
|
61
|
+
rescue Diffend::Errors::HandledException
|
62
|
+
return if ENV['DIFFEND_IGNORE_ERRORS'] == 'true'
|
63
|
+
|
64
|
+
exit 255
|
54
65
|
rescue StandardError => e
|
55
66
|
Diffend::HandleErrors::Report.call(
|
56
67
|
exception: e,
|
57
68
|
config: config,
|
58
69
|
message: :unhandled_exception,
|
59
|
-
report: true
|
70
|
+
report: true,
|
71
|
+
raise_exception: false
|
60
72
|
)
|
73
|
+
|
74
|
+
return if ENV['DIFFEND_IGNORE_ERRORS'] == 'true'
|
75
|
+
|
76
|
+
exit 255
|
77
|
+
end
|
78
|
+
|
79
|
+
def verify_version
|
80
|
+
return if ENV['DIFFEND_DEVELOPMENT'] == 'true'
|
81
|
+
return if installed_version == VERSION
|
82
|
+
|
83
|
+
build_outdated_version_message(installed_version)
|
84
|
+
.tap(&Bundler.ui.method(:error))
|
85
|
+
|
86
|
+
exit 2
|
87
|
+
end
|
88
|
+
|
89
|
+
# @return [String] installed plugin version
|
90
|
+
def installed_version
|
91
|
+
Bundler::Plugin
|
92
|
+
.index
|
93
|
+
.plugin_path('diffend')
|
94
|
+
.basename
|
95
|
+
.to_s
|
96
|
+
.split('-')
|
97
|
+
.last
|
98
|
+
end
|
99
|
+
|
100
|
+
# Checks if plugin is enabled
|
101
|
+
#
|
102
|
+
# @return [Boolean] true if enabled, false otherwise
|
103
|
+
def enabled?
|
104
|
+
Bundler
|
105
|
+
.default_gemfile
|
106
|
+
.read
|
107
|
+
.split("\n")
|
108
|
+
.reject(&:empty?)
|
109
|
+
.map(&:strip)
|
110
|
+
.select { |line| line.start_with?('plugin') }
|
111
|
+
.any? { |line| line.include?('diffend') }
|
112
|
+
end
|
113
|
+
|
114
|
+
# @param version [Hash] installed version
|
115
|
+
#
|
116
|
+
# @return [String]
|
117
|
+
def build_outdated_version_message(version)
|
118
|
+
<<~MSG
|
119
|
+
\nYou are running an outdated version (#{version}) of the plugin, which will lead to issues.
|
120
|
+
\nPlease upgrade to the latest one (#{VERSION}) by executing "rm -rf .bundle/plugin".\n
|
121
|
+
MSG
|
61
122
|
end
|
62
123
|
|
63
124
|
# Command that was run with bundle
|
data/lib/diffend/commands.rb
CHANGED
@@ -3,9 +3,11 @@
|
|
3
3
|
module Diffend
|
4
4
|
# Modules grouping supported bundler commands
|
5
5
|
module Commands
|
6
|
-
#
|
6
|
+
# Bundler install command
|
7
7
|
INSTALL = 'install'
|
8
|
-
#
|
8
|
+
# Bundler update command
|
9
9
|
UPDATE = 'update'
|
10
|
+
# Bundler exec command
|
11
|
+
EXEC = 'exec'
|
10
12
|
end
|
11
13
|
end
|
@@ -27,16 +27,20 @@ module Diffend
|
|
27
27
|
build(build_path)
|
28
28
|
rescue Errors::MissingConfigurationFile
|
29
29
|
Bundler.ui.error(build_missing_error_message(build_path))
|
30
|
-
|
30
|
+
|
31
|
+
raise Diffend::Errors::HandledException
|
31
32
|
rescue Errors::EmptyConfigurationFile
|
32
33
|
Bundler.ui.error(build_empty_error_message(build_path))
|
33
|
-
|
34
|
+
|
35
|
+
raise Diffend::Errors::HandledException
|
34
36
|
rescue Errors::MalformedConfigurationFile
|
35
37
|
Bundler.ui.error(build_malformed_error_message(build_path))
|
36
|
-
|
38
|
+
|
39
|
+
raise Diffend::Errors::HandledException
|
37
40
|
rescue *MISSING_KEY_ERRORS => e
|
38
41
|
Bundler.ui.error(build_missing_key_error_message(e))
|
39
|
-
|
42
|
+
|
43
|
+
raise Diffend::Errors::HandledException
|
40
44
|
end
|
41
45
|
|
42
46
|
private
|
data/lib/diffend/errors.rb
CHANGED
@@ -19,9 +19,9 @@ module Diffend
|
|
19
19
|
ShareableKeyMissingInConfigurationFile = Class.new(BaseError)
|
20
20
|
# Raised when build_path is missing in configuration file
|
21
21
|
BuildPathMissingInConfigurationFile = Class.new(BaseError)
|
22
|
-
#
|
23
|
-
|
24
|
-
#
|
25
|
-
|
22
|
+
# Raised when server-side error occurs
|
23
|
+
RequestServerError = Class.new(BaseError)
|
24
|
+
# Raised when we had an exception that we know how to handle
|
25
|
+
HandledException = Class.new(BaseError)
|
26
26
|
end
|
27
27
|
end
|
@@ -9,7 +9,7 @@ module Diffend
|
|
9
9
|
class << self
|
10
10
|
# Build exception payload
|
11
11
|
#
|
12
|
-
# @param exception [Exception] expection that was raised
|
12
|
+
# @param exception [Exception, NilClass] expection that was raised
|
13
13
|
# @param payload [Hash] with versions to check
|
14
14
|
#
|
15
15
|
# @return [Hash]
|
@@ -18,9 +18,9 @@ module Diffend
|
|
18
18
|
request_id: SecureRandom.uuid,
|
19
19
|
payload: payload,
|
20
20
|
exception: {
|
21
|
-
class: exception
|
22
|
-
message: exception
|
23
|
-
backtrace: exception
|
21
|
+
class: exception&.class,
|
22
|
+
message: exception&.message,
|
23
|
+
backtrace: exception&.backtrace
|
24
24
|
}
|
25
25
|
}.freeze
|
26
26
|
end
|
@@ -9,6 +9,16 @@ module Diffend
|
|
9
9
|
This is a bug, don't hesitate.\n
|
10
10
|
Create an issue at https://github.com/diffend-io/diffend-ruby/issues\n
|
11
11
|
MSG
|
12
|
+
UNSUPPORTED_RESPONSE = <<~MSG
|
13
|
+
\nAPI returned an unsupported response. We recorded this incident in our system and will review it.\n
|
14
|
+
This is a bug, don't hesitate.\n
|
15
|
+
Create an issue at https://github.com/diffend-io/diffend-ruby/issues\n
|
16
|
+
MSG
|
17
|
+
UNSUPPORTED_VERDICT = <<~MSG
|
18
|
+
\nAPI returned an unsupported verdict. We recorded this incident in our system and will review it.\n
|
19
|
+
This is a bug, don't hesitate.\n
|
20
|
+
Create an issue at https://github.com/diffend-io/diffend-ruby/issues\n
|
21
|
+
MSG
|
12
22
|
REQUEST_ERROR = <<~MSG
|
13
23
|
\nWe were unable to process your request at this time. We recorded this incident in our system and will review it.\n
|
14
24
|
If you think that this is a bug, don't hesitate.\n
|
@@ -12,9 +12,10 @@ module Diffend
|
|
12
12
|
# @param config [OpenStruct] Diffend config
|
13
13
|
# @param message [Symbol] message that we want to display
|
14
14
|
# @param report [Boolean] if true we will report the issue to diffend
|
15
|
+
# @param raise_exception [Boolean] if true we will raise an exception
|
15
16
|
#
|
16
17
|
# @return [Net::HTTPResponse] response from Diffend
|
17
|
-
def call(
|
18
|
+
def call(config:, message:, exception: nil, payload: {}, report: false, raise_exception: true)
|
18
19
|
exception_payload = prepare_exception_payload(exception, payload)
|
19
20
|
|
20
21
|
Bundler.ui.error(Diffend::HandleErrors::Messages::PAYLOAD_DUMP)
|
@@ -22,13 +23,24 @@ module Diffend
|
|
22
23
|
|
23
24
|
if report
|
24
25
|
Diffend::Request.call(
|
25
|
-
config,
|
26
|
-
errors_url(config.project_id),
|
27
|
-
exception_payload
|
26
|
+
build_request_object(config, exception_payload)
|
28
27
|
)
|
29
28
|
end
|
30
29
|
|
31
|
-
|
30
|
+
raise Diffend::Errors::HandledException if raise_exception
|
31
|
+
end
|
32
|
+
|
33
|
+
# @param config [OpenStruct] diffend config
|
34
|
+
# @param payload [Hash]
|
35
|
+
#
|
36
|
+
# @return [Diffend::RequestObject]
|
37
|
+
def build_request_object(config, payload)
|
38
|
+
Diffend::RequestObject.new(
|
39
|
+
config: config,
|
40
|
+
url: errors_url(config.project_id),
|
41
|
+
payload: payload,
|
42
|
+
request_method: :post
|
43
|
+
)
|
32
44
|
end
|
33
45
|
|
34
46
|
# Prepare exception payload and display it to stdout
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
%w[
|
4
|
+
build_bundler_definition
|
5
|
+
errors
|
6
|
+
config/fetcher
|
7
|
+
config/file_finder
|
8
|
+
config/validator
|
9
|
+
commands
|
10
|
+
handle_errors/messages
|
11
|
+
handle_errors/build_exception_payload
|
12
|
+
handle_errors/display_to_stdout
|
13
|
+
handle_errors/report
|
14
|
+
request_object
|
15
|
+
request
|
16
|
+
voting
|
17
|
+
track
|
18
|
+
].each { |file| require "diffend/#{file}" }
|
19
|
+
|
20
|
+
%w[
|
21
|
+
versions/local
|
22
|
+
versions/remote
|
23
|
+
].each { |file| require "diffend/voting/#{file}" }
|
24
|
+
|
25
|
+
unless %w[development test].include?(ENV['DIFFEND_ENV'])
|
26
|
+
Thread.new do
|
27
|
+
track = Diffend::Track.new
|
28
|
+
track.start
|
29
|
+
end
|
30
|
+
end
|
data/lib/diffend/request.rb
CHANGED
@@ -23,6 +23,15 @@ module Diffend
|
|
23
23
|
Net::OpenTimeout,
|
24
24
|
Net::ReadTimeout
|
25
25
|
].freeze
|
26
|
+
# Message displayed when server issue occured and we will retry
|
27
|
+
SERVER_ERROR_MESSAGE = 'We experienced a server-side issue, retrying...'
|
28
|
+
# List of server issues
|
29
|
+
#
|
30
|
+
# 500 - Internal Server Error
|
31
|
+
# 502 - Bad Gateway
|
32
|
+
# 503 - Service Unavailable
|
33
|
+
# 504 - Gateway Timeout
|
34
|
+
SERVER_ERRORS = [500, 502, 503, 504].freeze
|
26
35
|
# Number of retries
|
27
36
|
RETRIES = 3
|
28
37
|
# Request headers
|
@@ -33,17 +42,39 @@ module Diffend
|
|
33
42
|
class << self
|
34
43
|
# Execute request
|
35
44
|
#
|
36
|
-
# @param
|
37
|
-
# @param endpoint_url [String]
|
38
|
-
# @param payload [Hash]
|
45
|
+
# @param request_object [Diffend::RequestObject]
|
39
46
|
#
|
40
47
|
# @return [Net::HTTPResponse] response from Diffend
|
41
|
-
def call(
|
48
|
+
def call(request_object)
|
42
49
|
retry_count ||= -1
|
43
50
|
|
44
|
-
build_http(
|
45
|
-
http.request(
|
51
|
+
build_http(request_object.url) do |http, uri|
|
52
|
+
response = http.request(
|
53
|
+
build_request(
|
54
|
+
uri,
|
55
|
+
request_object.request_method,
|
56
|
+
request_object.config,
|
57
|
+
request_object.payload
|
58
|
+
)
|
59
|
+
)
|
60
|
+
|
61
|
+
if SERVER_ERRORS.include?(response.code.to_i)
|
62
|
+
raise Diffend::Errors::RequestServerError, response.code.to_i
|
63
|
+
end
|
64
|
+
|
65
|
+
response
|
46
66
|
end
|
67
|
+
rescue Diffend::Errors::RequestServerError => e
|
68
|
+
retry_count += 1
|
69
|
+
|
70
|
+
retry if handle_retry(SERVER_ERROR_MESSAGE, retry_count)
|
71
|
+
|
72
|
+
Diffend::HandleErrors::Report.call(
|
73
|
+
exception: e,
|
74
|
+
payload: request_object.payload,
|
75
|
+
config: request_object.config,
|
76
|
+
message: :request_error
|
77
|
+
)
|
47
78
|
rescue *CONNECTION_EXCEPTIONS => e
|
48
79
|
retry_count += 1
|
49
80
|
|
@@ -51,8 +82,8 @@ module Diffend
|
|
51
82
|
|
52
83
|
Diffend::HandleErrors::Report.call(
|
53
84
|
exception: e,
|
54
|
-
payload: payload,
|
55
|
-
config: config,
|
85
|
+
payload: request_object.payload,
|
86
|
+
config: request_object.config,
|
56
87
|
message: :request_error
|
57
88
|
)
|
58
89
|
rescue *TIMEOUT_EXCEPTIONS => e
|
@@ -62,8 +93,8 @@ module Diffend
|
|
62
93
|
|
63
94
|
Diffend::HandleErrors::Report.call(
|
64
95
|
exception: e,
|
65
|
-
payload: payload,
|
66
|
-
config: config,
|
96
|
+
payload: request_object.payload,
|
97
|
+
config: request_object.config,
|
67
98
|
message: :request_error
|
68
99
|
)
|
69
100
|
end
|
@@ -100,17 +131,32 @@ module Diffend
|
|
100
131
|
# Build http post request and assigns headers and payload
|
101
132
|
#
|
102
133
|
# @param uri [URI::HTTPS]
|
134
|
+
# @param request_method [Symbol]
|
103
135
|
# @param config [OpenStruct] Diffend config
|
104
136
|
# @param payload [Hash] with versions to check
|
105
137
|
#
|
106
|
-
# @return [Net::HTTP::Post]
|
107
|
-
def build_request(uri, config, payload)
|
108
|
-
|
138
|
+
# @return [Net::HTTP::Post, Net::HTTP::Put]
|
139
|
+
def build_request(uri, request_method, config, payload)
|
140
|
+
pick_request_method(request_method)
|
109
141
|
.new(uri.request_uri, HEADERS)
|
110
142
|
.tap { |request| assign_auth(request, config) }
|
111
143
|
.tap { |request| assign_payload(request, payload) }
|
112
144
|
end
|
113
145
|
|
146
|
+
# Pick request method
|
147
|
+
#
|
148
|
+
# @param request_method [Symbol]
|
149
|
+
#
|
150
|
+
# @return [Net::HTTP::Post, Net::HTTP::Put]
|
151
|
+
def pick_request_method(request_method)
|
152
|
+
case request_method
|
153
|
+
when :post
|
154
|
+
Net::HTTP::Post
|
155
|
+
when :put
|
156
|
+
Net::HTTP::Put
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
114
160
|
# Assigns basic authorization if provided in the config
|
115
161
|
#
|
116
162
|
# @param request [Net::HTTP::Post] prepared http post
|
@@ -0,0 +1,104 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Diffend
|
4
|
+
# Track what is run in production
|
5
|
+
class Track
|
6
|
+
# Time that we want to wait between track requests
|
7
|
+
TRACK_SLEEP = 15
|
8
|
+
# Time that we want to wait before we retry
|
9
|
+
RETRY_SLEEP = 15
|
10
|
+
|
11
|
+
# Initialize tracking
|
12
|
+
def initialize
|
13
|
+
@mutex = Mutex.new
|
14
|
+
@config = fetch_config
|
15
|
+
end
|
16
|
+
|
17
|
+
# Start tracking
|
18
|
+
def start
|
19
|
+
response = exec_request
|
20
|
+
|
21
|
+
perform(response['id'])
|
22
|
+
rescue Diffend::Errors::HandledException
|
23
|
+
sleep(RETRY_SLEEP)
|
24
|
+
|
25
|
+
retry
|
26
|
+
rescue StandardError => e
|
27
|
+
Diffend::HandleErrors::Report.call(
|
28
|
+
exception: e,
|
29
|
+
config: @config,
|
30
|
+
message: :unhandled_exception,
|
31
|
+
report: true,
|
32
|
+
raise_exception: false
|
33
|
+
)
|
34
|
+
|
35
|
+
sleep(RETRY_SLEEP)
|
36
|
+
|
37
|
+
retry
|
38
|
+
end
|
39
|
+
|
40
|
+
# @param request_id [String]
|
41
|
+
def perform(request_id)
|
42
|
+
loop do
|
43
|
+
@mutex.synchronize do
|
44
|
+
track_request(request_id)
|
45
|
+
end
|
46
|
+
|
47
|
+
sleep(TRACK_SLEEP)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Perform an exec request
|
52
|
+
def exec_request
|
53
|
+
Diffend::Voting.call(
|
54
|
+
Diffend::Commands::EXEC,
|
55
|
+
@config,
|
56
|
+
Diffend::BuildBundlerDefinition.call(
|
57
|
+
Diffend::Commands::EXEC,
|
58
|
+
Bundler.default_gemfile,
|
59
|
+
Bundler.default_lockfile
|
60
|
+
)
|
61
|
+
)
|
62
|
+
end
|
63
|
+
|
64
|
+
# Perform a track request
|
65
|
+
#
|
66
|
+
# @param request_id [String]
|
67
|
+
def track_request(request_id)
|
68
|
+
Diffend::Request.call(
|
69
|
+
build_request_object(request_id)
|
70
|
+
)
|
71
|
+
end
|
72
|
+
|
73
|
+
# @param request_id [String]
|
74
|
+
#
|
75
|
+
# @return [Diffend::RequestObject]
|
76
|
+
def build_request_object(request_id)
|
77
|
+
Diffend::RequestObject.new(
|
78
|
+
config: @config,
|
79
|
+
url: track_url(@config.project_id, request_id),
|
80
|
+
payload: { id: request_id }.freeze,
|
81
|
+
request_method: :put
|
82
|
+
).freeze
|
83
|
+
end
|
84
|
+
|
85
|
+
# Fetch diffend config file
|
86
|
+
#
|
87
|
+
# @return [OpenStruct, nil] configuration object
|
88
|
+
#
|
89
|
+
# @raise [Errors::MissingConfigurationFile] when no config file
|
90
|
+
def fetch_config
|
91
|
+
Config::Fetcher.call(
|
92
|
+
File.expand_path('..', Bundler.bin_path)
|
93
|
+
)
|
94
|
+
end
|
95
|
+
|
96
|
+
# @param project_id [String] diffend project_id
|
97
|
+
# @param request_id [String]
|
98
|
+
#
|
99
|
+
# @return [String]
|
100
|
+
def track_url(project_id, request_id)
|
101
|
+
"https://my.diffend.io/api/projects/#{project_id}/bundle/#{request_id}/track"
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
data/lib/diffend/voting.rb
CHANGED
@@ -7,45 +7,69 @@ module Diffend
|
|
7
7
|
# Build verdict
|
8
8
|
#
|
9
9
|
# @param command [String] either install or update
|
10
|
+
# @param config [OpenStruct] diffend config
|
10
11
|
# @param definition [Bundler::Definition] definition for your source
|
11
|
-
def call(command, definition)
|
12
|
+
def call(command, config, definition)
|
12
13
|
Versions::Remote
|
13
|
-
.call(command, definition)
|
14
|
-
.tap { |response| build_message(command, response) }
|
14
|
+
.call(command, config, definition)
|
15
|
+
.tap { |response| build_message(command, config, response) }
|
15
16
|
end
|
16
17
|
|
17
|
-
|
18
|
+
# @param command [String] either install or update
|
19
|
+
# @param config [OpenStruct] diffend config
|
20
|
+
# @param response [Hash] response from diffend API
|
21
|
+
def build_message(command, config, response)
|
18
22
|
if response.key?('error')
|
19
23
|
build_error(response)
|
20
24
|
elsif response.key?('action')
|
21
|
-
build_verdict(command, response)
|
25
|
+
build_verdict(command, config, response)
|
22
26
|
else
|
23
|
-
|
27
|
+
Diffend::HandleErrors::Report.call(
|
28
|
+
config: config,
|
29
|
+
message: :unsupported_response,
|
30
|
+
payload: response,
|
31
|
+
report: true
|
32
|
+
)
|
24
33
|
end
|
25
34
|
end
|
26
35
|
|
36
|
+
# @param response [Hash] response from diffend API
|
27
37
|
def build_error(response)
|
28
38
|
build_error_message(response)
|
29
39
|
.tap(&Bundler.ui.method(:error))
|
30
40
|
|
31
|
-
|
41
|
+
raise Diffend::Errors::HandledException
|
32
42
|
end
|
33
43
|
|
34
|
-
|
44
|
+
# @param command [String] either install or update
|
45
|
+
# @param config [OpenStruct] diffend config
|
46
|
+
# @param response [Hash] response from diffend API
|
47
|
+
def build_verdict(command, config, response)
|
35
48
|
case response['action']
|
36
49
|
when 'allow'
|
37
50
|
build_allow_message(command, response)
|
38
51
|
.tap(&Bundler.ui.method(:confirm))
|
52
|
+
when 'warn'
|
53
|
+
build_warn_message(command, response)
|
54
|
+
.tap(&Bundler.ui.method(:warn))
|
39
55
|
when 'deny'
|
40
56
|
build_deny_message(command, response)
|
41
57
|
.tap(&Bundler.ui.method(:error))
|
42
58
|
|
43
59
|
exit 1
|
44
60
|
else
|
45
|
-
|
61
|
+
Diffend::HandleErrors::Report.call(
|
62
|
+
config: config,
|
63
|
+
message: :unsupported_verdict,
|
64
|
+
payload: response,
|
65
|
+
report: true
|
66
|
+
)
|
46
67
|
end
|
47
68
|
end
|
48
69
|
|
70
|
+
# @param response [Hash] response from diffend API
|
71
|
+
#
|
72
|
+
# @return [String]
|
49
73
|
def build_error_message(response)
|
50
74
|
<<~MSG
|
51
75
|
\nDiffend returned an error for your request.\n
|
@@ -53,21 +77,56 @@ module Diffend
|
|
53
77
|
MSG
|
54
78
|
end
|
55
79
|
|
80
|
+
# @param command [String] either install or update
|
81
|
+
# @param response [Hash] response from diffend API
|
82
|
+
#
|
83
|
+
# @return [String]
|
56
84
|
def build_allow_message(command, response)
|
57
85
|
<<~MSG
|
58
|
-
|
59
|
-
|
86
|
+
#{build_message_header('an allow', command)}
|
87
|
+
#{build_message_info(response)}\n
|
60
88
|
#{response['review_url']}\n
|
61
89
|
MSG
|
62
90
|
end
|
63
91
|
|
92
|
+
# @param command [String] either install or update
|
93
|
+
# @param response [Hash] response from diffend API
|
94
|
+
#
|
95
|
+
# @return [String]
|
96
|
+
def build_warn_message(command, response)
|
97
|
+
<<~MSG
|
98
|
+
#{build_message_header('a warn', command)}
|
99
|
+
#{build_message_info(response)} Please go to the url below and review the issues.\n
|
100
|
+
#{response['review_url']}\n
|
101
|
+
MSG
|
102
|
+
end
|
103
|
+
|
104
|
+
# @param command [String] either install or update
|
105
|
+
# @param response [Hash] response from diffend API
|
106
|
+
#
|
107
|
+
# @return [String]
|
64
108
|
def build_deny_message(command, response)
|
65
109
|
<<~MSG
|
66
|
-
|
67
|
-
#{response
|
110
|
+
#{build_message_header('a deny', command)}
|
111
|
+
#{build_message_info(response)} Please go to the url below and review the issues.\n
|
68
112
|
#{response['review_url']}\n
|
69
113
|
MSG
|
70
114
|
end
|
115
|
+
|
116
|
+
# @param type [String] verdict type
|
117
|
+
# @param command [String] either install or update
|
118
|
+
#
|
119
|
+
# @return [String]
|
120
|
+
def build_message_header(type, command)
|
121
|
+
"\nDiffend reported #{type} verdict for #{command} command for this project."
|
122
|
+
end
|
123
|
+
|
124
|
+
# @param response [Hash] response from diffend API
|
125
|
+
#
|
126
|
+
# @return [String]
|
127
|
+
def build_message_info(response)
|
128
|
+
"\nQuality score: #{response['quality_score']}, allows: #{response['allows_count']}, warnings: #{response['warns_count']}, denies: #{response['denies_count']}."
|
129
|
+
end
|
71
130
|
end
|
72
131
|
end
|
73
132
|
end
|
@@ -40,7 +40,7 @@ module Diffend
|
|
40
40
|
instance = new(definition)
|
41
41
|
|
42
42
|
case command
|
43
|
-
when Commands::INSTALL then instance.build_install
|
43
|
+
when Commands::INSTALL, Commands::EXEC then instance.build_install
|
44
44
|
when Commands::UPDATE then instance.build_update
|
45
45
|
else
|
46
46
|
raise ArgumentError, "invalid command: #{command}"
|
@@ -54,7 +54,6 @@ module Diffend
|
|
54
54
|
def initialize(definition)
|
55
55
|
@definition = definition
|
56
56
|
@direct_dependencies = Hash[definition.dependencies.map { |val| [val.name, val] }]
|
57
|
-
@main_source = definition.send(:sources).rubygems_sources.last
|
58
57
|
# Support case without Gemfile.lock
|
59
58
|
@locked_specs = @definition.locked_gems ? @definition.locked_gems.specs : []
|
60
59
|
end
|
@@ -150,17 +149,17 @@ module Diffend
|
|
150
149
|
#
|
151
150
|
# @return [String]
|
152
151
|
def build_spec_platform(spec, locked_spec)
|
153
|
-
|
152
|
+
parse_platform(
|
153
|
+
spec.platform || locked_spec&.platform || spec.send(:generic_local_platform)
|
154
|
+
)
|
154
155
|
end
|
155
156
|
|
156
|
-
#
|
157
|
+
# Parse gem platform
|
157
158
|
#
|
158
|
-
# @param
|
159
|
+
# @param platform [String, Gem::Platform]
|
159
160
|
#
|
160
161
|
# @return [String]
|
161
|
-
def
|
162
|
-
platform = spec.send(:generic_local_platform)
|
163
|
-
|
162
|
+
def parse_platform(platform)
|
164
163
|
case platform
|
165
164
|
when String then platform
|
166
165
|
when Gem::Platform then platform.os
|
@@ -176,7 +175,7 @@ module Diffend
|
|
176
175
|
case source
|
177
176
|
when Bundler::Source::Metadata
|
178
177
|
GEM_SOURCES_TYPES[:local]
|
179
|
-
when Bundler::Source::Rubygems
|
178
|
+
when Bundler::Source::Rubygems, Bundler::Source::Rubygems::Remote
|
180
179
|
GEM_SOURCES_TYPES[:gemfile_source]
|
181
180
|
when Bundler::Source::Git
|
182
181
|
GEM_SOURCES_TYPES[:gemfile_git]
|
@@ -207,10 +206,20 @@ module Diffend
|
|
207
206
|
#
|
208
207
|
# @return [Bundler::Source] gem source type
|
209
208
|
def source_for_spec(spec)
|
210
|
-
if
|
211
|
-
|
212
|
-
|
209
|
+
return spec.remote if spec.remote
|
210
|
+
|
211
|
+
case spec.source
|
212
|
+
when Bundler::Source::Rubygems
|
213
|
+
spec
|
214
|
+
.source
|
215
|
+
.send(:remote_specs)
|
216
|
+
.search(Bundler::Dependency.new(spec.name, spec.version))
|
217
|
+
.last
|
218
|
+
.remote
|
219
|
+
when Bundler::Source::Metadata, Bundler::Source::Git, Bundler::Source::Path
|
213
220
|
spec.source
|
221
|
+
else
|
222
|
+
raise ArgumentError, "unknown source #{spec.source.class}"
|
214
223
|
end
|
215
224
|
end
|
216
225
|
|
@@ -223,10 +232,10 @@ module Diffend
|
|
223
232
|
case source
|
224
233
|
when Bundler::Source::Metadata
|
225
234
|
''
|
226
|
-
when Bundler::Source::Rubygems
|
227
|
-
source_name(source.
|
235
|
+
when Bundler::Source::Rubygems::Remote
|
236
|
+
source_name(source.anonymized_uri)
|
228
237
|
when Bundler::Source::Git
|
229
|
-
source.
|
238
|
+
source.instance_variable_get(:@safe_uri)
|
230
239
|
when Bundler::Source::Path
|
231
240
|
source.path
|
232
241
|
else
|
@@ -234,11 +243,11 @@ module Diffend
|
|
234
243
|
end
|
235
244
|
end
|
236
245
|
|
237
|
-
# @param
|
246
|
+
# @param uri [Bundler::URI]
|
238
247
|
#
|
239
|
-
# @return [String]
|
240
|
-
def source_name(
|
241
|
-
|
248
|
+
# @return [String]
|
249
|
+
def source_name(uri)
|
250
|
+
uri.to_s[0...-1]
|
242
251
|
end
|
243
252
|
|
244
253
|
# Build sources used in the Gemfile
|
@@ -20,28 +20,39 @@ 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
|
-
|
23
|
+
# @param config [OpenStruct] diffend config
|
24
|
+
def call(command, config, definition)
|
26
25
|
payload = payload(command, config.project_id, definition)
|
27
26
|
|
28
27
|
response = Diffend::Request.call(
|
29
|
-
config,
|
30
|
-
commands_url(command, config.project_id),
|
31
|
-
payload
|
28
|
+
build_request_object(command, config, payload)
|
32
29
|
)
|
33
30
|
|
34
31
|
JSON.parse(response.body)
|
35
32
|
rescue StandardError => e
|
36
33
|
Diffend::HandleErrors::Report.call(
|
37
34
|
exception: e,
|
38
|
-
payload: payload,
|
35
|
+
payload: payload || {},
|
39
36
|
config: config,
|
40
37
|
message: :unhandled_exception,
|
41
38
|
report: true
|
42
39
|
)
|
43
40
|
end
|
44
41
|
|
42
|
+
# @param command [String] either install or update
|
43
|
+
# @param config [OpenStruct] diffend config
|
44
|
+
# @param payload [Hash]
|
45
|
+
#
|
46
|
+
# @return [Diffend::RequestObject]
|
47
|
+
def build_request_object(command, config, payload)
|
48
|
+
Diffend::RequestObject.new(
|
49
|
+
config: config,
|
50
|
+
url: commands_url(command, config.project_id),
|
51
|
+
payload: payload,
|
52
|
+
request_method: :post
|
53
|
+
)
|
54
|
+
end
|
55
|
+
|
45
56
|
# Build diffend, host, packages, and platform specific information
|
46
57
|
#
|
47
58
|
# @param command [String] either install or update
|
@@ -151,10 +162,16 @@ module Diffend
|
|
151
162
|
#
|
152
163
|
# @return [Hash]
|
153
164
|
def build_host_command
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
165
|
+
if File.exist?($PROGRAM_NAME)
|
166
|
+
array = `ps -p #{Process.pid} -o command=`.strip.split(' ')
|
167
|
+
array.shift if array.first.end_with?('bin/ruby')
|
168
|
+
name = array.shift.split('/').last.strip
|
169
|
+
command = "#{name} #{array.join(' ')}"
|
170
|
+
|
171
|
+
{ 'name' => command, 'title' => '' }
|
172
|
+
else
|
173
|
+
{ 'name' => ARGV.join(' '), 'title' => $PROGRAM_NAME }
|
174
|
+
end
|
158
175
|
end
|
159
176
|
|
160
177
|
# Build host ips, except localhost and loopback
|
@@ -187,17 +204,6 @@ module Diffend
|
|
187
204
|
tags
|
188
205
|
end
|
189
206
|
|
190
|
-
# Fetch diffend config file
|
191
|
-
#
|
192
|
-
# @return [OpenStruct, nil] configuration object
|
193
|
-
#
|
194
|
-
# @raise [Errors::MissingConfigurationFile] when no config file
|
195
|
-
def fetch_config
|
196
|
-
Config::Fetcher.call(
|
197
|
-
File.expand_path('..', Bundler.bin_path)
|
198
|
-
)
|
199
|
-
end
|
200
|
-
|
201
207
|
# Provides diffend command endpoint url
|
202
208
|
#
|
203
209
|
# @param command [String] either install or update
|
@@ -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.28
|
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-09-
|
37
|
+
date: 2020-09-19 00:00:00.000000000 Z
|
38
38
|
dependencies:
|
39
39
|
- !ruby/object:Gem::Dependency
|
40
40
|
name: bundler
|
@@ -102,7 +102,10 @@ files:
|
|
102
102
|
- lib/diffend/handle_errors/display_to_stdout.rb
|
103
103
|
- lib/diffend/handle_errors/messages.rb
|
104
104
|
- lib/diffend/handle_errors/report.rb
|
105
|
+
- lib/diffend/monitor.rb
|
105
106
|
- lib/diffend/request.rb
|
107
|
+
- lib/diffend/request_object.rb
|
108
|
+
- lib/diffend/track.rb
|
106
109
|
- lib/diffend/voting.rb
|
107
110
|
- lib/diffend/voting/versions/local.rb
|
108
111
|
- lib/diffend/voting/versions/remote.rb
|
metadata.gz.sig
CHANGED
Binary file
|