diffend 0.2.23 → 0.2.28
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 +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
|