diffend 0.2.27 → 0.2.32
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/CHANGELOG.md +29 -1
- data/Gemfile.lock +1 -1
- data/diffend.gemspec +2 -3
- data/lib/diffend.rb +0 -138
- data/lib/diffend/build_bundler_definition.rb +1 -1
- data/lib/diffend/config.rb +81 -0
- data/lib/diffend/{config → configs}/fetcher.rb +11 -39
- data/lib/diffend/{config → configs}/file_finder.rb +1 -1
- data/lib/diffend/configs/validator.rb +85 -0
- data/lib/diffend/errors.rb +2 -0
- data/lib/diffend/{voting.rb → execute.rb} +37 -28
- data/lib/diffend/handle_errors/report.rb +9 -17
- data/lib/diffend/latest_version.rb +50 -0
- data/lib/diffend/local_context.rb +23 -0
- data/lib/diffend/local_context/diffend.rb +33 -0
- data/lib/diffend/local_context/host.rb +88 -0
- data/lib/diffend/local_context/packages.rb +302 -0
- data/lib/diffend/local_context/platform.rb +58 -0
- data/lib/diffend/logger.rb +66 -0
- data/lib/diffend/monitor.rb +21 -10
- data/lib/diffend/plugin.rb +86 -0
- data/lib/diffend/request.rb +10 -10
- data/lib/diffend/request_verdict.rb +45 -0
- data/lib/diffend/track.rb +7 -39
- data/lib/diffend/version.rb +6 -0
- data/plugins.rb +2 -2
- data/scripts/generate_payload_for_file.rb +1 -2
- metadata +18 -9
- metadata.gz.sig +0 -0
- data/lib/diffend/config/validator.rb +0 -25
- data/lib/diffend/voting/versions/local.rb +0 -304
- data/lib/diffend/voting/versions/remote.rb +0 -216
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Diffend
|
|
4
|
+
# Module responsible for building local context
|
|
5
|
+
module LocalContext
|
|
6
|
+
# Module responsible for building platform information from local context
|
|
7
|
+
module Platform
|
|
8
|
+
class << self
|
|
9
|
+
# Build platform information
|
|
10
|
+
#
|
|
11
|
+
# @return [Hash]
|
|
12
|
+
def call
|
|
13
|
+
{
|
|
14
|
+
'bundler' => {
|
|
15
|
+
'version' => Bundler::VERSION
|
|
16
|
+
},
|
|
17
|
+
'environment' => environment,
|
|
18
|
+
'ruby' => ruby_information,
|
|
19
|
+
'rubygems' => {
|
|
20
|
+
'specification_version' => Gem::Specification::CURRENT_SPECIFICATION_VERSION,
|
|
21
|
+
'version' => Gem::VERSION
|
|
22
|
+
}
|
|
23
|
+
}.freeze
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
# Build platform ruby information
|
|
29
|
+
#
|
|
30
|
+
# @return [Hash]
|
|
31
|
+
def ruby_information
|
|
32
|
+
if defined?(JRUBY_VERSION)
|
|
33
|
+
revision = JRUBY_REVISION.to_s
|
|
34
|
+
version = JRUBY_VERSION
|
|
35
|
+
else
|
|
36
|
+
revision = RUBY_REVISION.to_s
|
|
37
|
+
version = RUBY_ENGINE_VERSION
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
{
|
|
41
|
+
'engine' => RUBY_ENGINE,
|
|
42
|
+
'patchlevel' => RUBY_PATCHLEVEL,
|
|
43
|
+
'release_date' => RUBY_RELEASE_DATE,
|
|
44
|
+
'revision' => revision,
|
|
45
|
+
'version' => version
|
|
46
|
+
}
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Build platform environment information
|
|
50
|
+
#
|
|
51
|
+
# @return [String]
|
|
52
|
+
def environment
|
|
53
|
+
ENV['RAILS_ENV'] || ENV['RACK_ENV'] || 'development'
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Diffend
|
|
4
|
+
# Diffend logging
|
|
5
|
+
class Logger
|
|
6
|
+
# Low-level information, mostly for developers.
|
|
7
|
+
DEBUG = 0
|
|
8
|
+
# Generic (useful) information about system operation.
|
|
9
|
+
INFO = 1
|
|
10
|
+
# A warning.
|
|
11
|
+
WARN = 2
|
|
12
|
+
# A handleable error condition.
|
|
13
|
+
ERROR = 3
|
|
14
|
+
# An unhandleable error that results in a program crash.
|
|
15
|
+
FATAL = 4
|
|
16
|
+
# An unknown message that should always be logged.
|
|
17
|
+
UNKNOWN = 5
|
|
18
|
+
|
|
19
|
+
# @param level [Integer] logging severity threshold
|
|
20
|
+
def initialize(level = INFO)
|
|
21
|
+
@level = level
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# @param message [String]
|
|
25
|
+
def debug(message)
|
|
26
|
+
log(DEBUG, message)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# @param message [String]
|
|
30
|
+
def info(message)
|
|
31
|
+
log(INFO, message)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# @param message [String]
|
|
35
|
+
def warn(message)
|
|
36
|
+
log(WARN, message)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# @param message [String]
|
|
40
|
+
def error(message)
|
|
41
|
+
log(ERROR, message)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# @param message [String]
|
|
45
|
+
def fatal(message)
|
|
46
|
+
log(FATAL, message)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
private
|
|
50
|
+
|
|
51
|
+
# @param severity [Integer]
|
|
52
|
+
# @param message [String]
|
|
53
|
+
def log(severity, message)
|
|
54
|
+
return if severity < @level
|
|
55
|
+
|
|
56
|
+
case severity
|
|
57
|
+
when INFO
|
|
58
|
+
Bundler.ui.confirm(message)
|
|
59
|
+
when WARN
|
|
60
|
+
Bundler.ui.warn(message)
|
|
61
|
+
when ERROR, FATAL
|
|
62
|
+
Bundler.ui.error(message)
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
data/lib/diffend/monitor.rb
CHANGED
|
@@ -1,28 +1,39 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
%w[
|
|
4
|
-
|
|
4
|
+
version
|
|
5
|
+
logger
|
|
5
6
|
errors
|
|
6
|
-
|
|
7
|
-
config/file_finder
|
|
8
|
-
config/validator
|
|
7
|
+
build_bundler_definition
|
|
9
8
|
commands
|
|
9
|
+
config
|
|
10
|
+
configs/fetcher
|
|
11
|
+
configs/file_finder
|
|
12
|
+
configs/validator
|
|
10
13
|
handle_errors/messages
|
|
11
14
|
handle_errors/build_exception_payload
|
|
12
15
|
handle_errors/display_to_stdout
|
|
13
16
|
handle_errors/report
|
|
14
17
|
request_object
|
|
15
18
|
request
|
|
16
|
-
|
|
19
|
+
local_context/diffend
|
|
20
|
+
local_context/host
|
|
21
|
+
local_context/packages
|
|
22
|
+
local_context/platform
|
|
23
|
+
local_context
|
|
24
|
+
request_verdict
|
|
25
|
+
execute
|
|
17
26
|
track
|
|
18
27
|
].each { |file| require "diffend/#{file}" }
|
|
19
28
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
29
|
+
config = Diffend::Config.new(
|
|
30
|
+
command: Diffend::Commands::EXEC,
|
|
31
|
+
severity: Diffend::Logger::FATAL
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
return if %w[development test].include?(config.env)
|
|
24
35
|
|
|
25
36
|
Thread.new do
|
|
26
|
-
track = Diffend::Track.new
|
|
37
|
+
track = Diffend::Track.new(config)
|
|
27
38
|
track.start
|
|
28
39
|
end
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
%w[
|
|
4
|
+
bundler
|
|
5
|
+
].each(&method(:require))
|
|
6
|
+
|
|
7
|
+
%w[
|
|
8
|
+
version
|
|
9
|
+
logger
|
|
10
|
+
latest_version
|
|
11
|
+
errors
|
|
12
|
+
build_bundler_definition
|
|
13
|
+
commands
|
|
14
|
+
config
|
|
15
|
+
configs/fetcher
|
|
16
|
+
configs/file_finder
|
|
17
|
+
configs/validator
|
|
18
|
+
handle_errors/messages
|
|
19
|
+
handle_errors/build_exception_payload
|
|
20
|
+
handle_errors/display_to_stdout
|
|
21
|
+
handle_errors/report
|
|
22
|
+
request_object
|
|
23
|
+
request
|
|
24
|
+
local_context/diffend
|
|
25
|
+
local_context/host
|
|
26
|
+
local_context/packages
|
|
27
|
+
local_context/platform
|
|
28
|
+
local_context
|
|
29
|
+
request_verdict
|
|
30
|
+
execute
|
|
31
|
+
track
|
|
32
|
+
].each { |file| require "diffend/#{file}" }
|
|
33
|
+
|
|
34
|
+
module Diffend
|
|
35
|
+
module Plugin
|
|
36
|
+
class << self
|
|
37
|
+
# Registers the plugin and add before install all hook
|
|
38
|
+
def register
|
|
39
|
+
::Bundler::Plugin.add_hook('before-install-all') do |_|
|
|
40
|
+
execute
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Execute diffend plugin
|
|
45
|
+
def execute
|
|
46
|
+
return unless enabled?
|
|
47
|
+
|
|
48
|
+
config = Diffend::Config.new(severity: Diffend::Logger::INFO)
|
|
49
|
+
|
|
50
|
+
Diffend::LatestVersion.call(config)
|
|
51
|
+
|
|
52
|
+
Diffend::Execute.call(config)
|
|
53
|
+
rescue Diffend::Errors::HandledException
|
|
54
|
+
return if config.ignore_errors?
|
|
55
|
+
|
|
56
|
+
exit 255
|
|
57
|
+
rescue StandardError => e
|
|
58
|
+
Diffend::HandleErrors::Report.call(
|
|
59
|
+
exception: e,
|
|
60
|
+
config: config,
|
|
61
|
+
message: :unhandled_exception,
|
|
62
|
+
report: true,
|
|
63
|
+
raise_exception: false
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
return if config.ignore_errors?
|
|
67
|
+
|
|
68
|
+
exit 255
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Checks if plugin is enabled
|
|
72
|
+
#
|
|
73
|
+
# @return [Boolean] true if enabled, false otherwise
|
|
74
|
+
def enabled?
|
|
75
|
+
::Bundler
|
|
76
|
+
.default_gemfile
|
|
77
|
+
.read
|
|
78
|
+
.split("\n")
|
|
79
|
+
.reject(&:empty?)
|
|
80
|
+
.map(&:strip)
|
|
81
|
+
.select { |line| line.start_with?('plugin') }
|
|
82
|
+
.any? { |line| line.include?('diffend') }
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
data/lib/diffend/request.rb
CHANGED
|
@@ -67,7 +67,7 @@ module Diffend
|
|
|
67
67
|
rescue Diffend::Errors::RequestServerError => e
|
|
68
68
|
retry_count += 1
|
|
69
69
|
|
|
70
|
-
retry if handle_retry(SERVER_ERROR_MESSAGE, retry_count)
|
|
70
|
+
retry if handle_retry(request_object.config, SERVER_ERROR_MESSAGE, retry_count)
|
|
71
71
|
|
|
72
72
|
Diffend::HandleErrors::Report.call(
|
|
73
73
|
exception: e,
|
|
@@ -78,7 +78,7 @@ module Diffend
|
|
|
78
78
|
rescue *CONNECTION_EXCEPTIONS => e
|
|
79
79
|
retry_count += 1
|
|
80
80
|
|
|
81
|
-
retry if handle_retry(CONNECTION_MESSAGE, retry_count)
|
|
81
|
+
retry if handle_retry(request_object.config, CONNECTION_MESSAGE, retry_count)
|
|
82
82
|
|
|
83
83
|
Diffend::HandleErrors::Report.call(
|
|
84
84
|
exception: e,
|
|
@@ -89,7 +89,7 @@ module Diffend
|
|
|
89
89
|
rescue *TIMEOUT_EXCEPTIONS => e
|
|
90
90
|
retry_count += 1
|
|
91
91
|
|
|
92
|
-
retry if handle_retry(TIMEOUT_MESSAGE, retry_count)
|
|
92
|
+
retry if handle_retry(request_object.config, TIMEOUT_MESSAGE, retry_count)
|
|
93
93
|
|
|
94
94
|
Diffend::HandleErrors::Report.call(
|
|
95
95
|
exception: e,
|
|
@@ -101,12 +101,13 @@ module Diffend
|
|
|
101
101
|
|
|
102
102
|
# Handle retry
|
|
103
103
|
#
|
|
104
|
+
# @param config [Diffend::Config]
|
|
104
105
|
# @param message [String] message we want to display
|
|
105
106
|
# @param retry_count [Integer]
|
|
106
|
-
def handle_retry(message, retry_count)
|
|
107
|
+
def handle_retry(config, message, retry_count)
|
|
107
108
|
return false if retry_count == RETRIES
|
|
108
109
|
|
|
109
|
-
|
|
110
|
+
config.logger.warn(message)
|
|
110
111
|
sleep(exponential_backoff(retry_count))
|
|
111
112
|
|
|
112
113
|
retry_count < RETRIES
|
|
@@ -123,8 +124,8 @@ module Diffend
|
|
|
123
124
|
uri.port,
|
|
124
125
|
use_ssl: uri.scheme == 'https',
|
|
125
126
|
verify_mode: OpenSSL::SSL::VERIFY_NONE,
|
|
126
|
-
open_timeout:
|
|
127
|
-
read_timeout:
|
|
127
|
+
open_timeout: 15,
|
|
128
|
+
read_timeout: 15
|
|
128
129
|
) { |http| yield(http, uri) }
|
|
129
130
|
end
|
|
130
131
|
|
|
@@ -132,7 +133,7 @@ module Diffend
|
|
|
132
133
|
#
|
|
133
134
|
# @param uri [URI::HTTPS]
|
|
134
135
|
# @param request_method [Symbol]
|
|
135
|
-
# @param config [
|
|
136
|
+
# @param config [Diffend::Config]
|
|
136
137
|
# @param payload [Hash] with versions to check
|
|
137
138
|
#
|
|
138
139
|
# @return [Net::HTTP::Post, Net::HTTP::Put]
|
|
@@ -160,9 +161,8 @@ module Diffend
|
|
|
160
161
|
# Assigns basic authorization if provided in the config
|
|
161
162
|
#
|
|
162
163
|
# @param request [Net::HTTP::Post] prepared http post
|
|
163
|
-
# @param config [
|
|
164
|
+
# @param config [Diffend::Config]
|
|
164
165
|
def assign_auth(request, config)
|
|
165
|
-
return unless config
|
|
166
166
|
return unless config.shareable_id
|
|
167
167
|
return unless config.shareable_key
|
|
168
168
|
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'json'
|
|
4
|
+
|
|
5
|
+
module Diffend
|
|
6
|
+
# Module responsible for fetching diffend verdict on local context
|
|
7
|
+
module RequestVerdict
|
|
8
|
+
class << self
|
|
9
|
+
# @param config [Diffend::Config]
|
|
10
|
+
# @param definition [Bundler::Definition] definition for your source
|
|
11
|
+
def call(config, definition)
|
|
12
|
+
payload = Diffend::LocalContext.call(config, definition)
|
|
13
|
+
|
|
14
|
+
response = Diffend::Request.call(
|
|
15
|
+
build_request_object(config, payload)
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
JSON.parse(response.body)
|
|
19
|
+
rescue Bundler::GemNotFound, Bundler::VersionConflict
|
|
20
|
+
raise ::Diffend::Errors::DependenciesResolveException
|
|
21
|
+
rescue StandardError => e
|
|
22
|
+
Diffend::HandleErrors::Report.call(
|
|
23
|
+
exception: e,
|
|
24
|
+
payload: payload || {},
|
|
25
|
+
config: config,
|
|
26
|
+
message: :unhandled_exception,
|
|
27
|
+
report: true
|
|
28
|
+
)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# @param config [Diffend::Config]
|
|
32
|
+
# @param payload [Hash]
|
|
33
|
+
#
|
|
34
|
+
# @return [Diffend::RequestObject]
|
|
35
|
+
def build_request_object(config, payload)
|
|
36
|
+
Diffend::RequestObject.new(
|
|
37
|
+
config: config,
|
|
38
|
+
url: config.commands_url,
|
|
39
|
+
payload: payload,
|
|
40
|
+
request_method: :post
|
|
41
|
+
)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
data/lib/diffend/track.rb
CHANGED
|
@@ -9,14 +9,16 @@ module Diffend
|
|
|
9
9
|
RETRY_SLEEP = 15
|
|
10
10
|
|
|
11
11
|
# Initialize tracking
|
|
12
|
-
|
|
12
|
+
#
|
|
13
|
+
# @param config [Diffend::Config]
|
|
14
|
+
def initialize(config)
|
|
13
15
|
@mutex = Mutex.new
|
|
14
|
-
@config =
|
|
16
|
+
@config = config
|
|
15
17
|
end
|
|
16
18
|
|
|
17
19
|
# Start tracking
|
|
18
20
|
def start
|
|
19
|
-
response =
|
|
21
|
+
response = Diffend::Execute.call(@config)
|
|
20
22
|
|
|
21
23
|
perform(response['id'])
|
|
22
24
|
rescue Diffend::Errors::HandledException
|
|
@@ -40,27 +42,12 @@ module Diffend
|
|
|
40
42
|
# @param request_id [String]
|
|
41
43
|
def perform(request_id)
|
|
42
44
|
loop do
|
|
43
|
-
@mutex.synchronize
|
|
44
|
-
track_request(request_id)
|
|
45
|
-
end
|
|
45
|
+
@mutex.synchronize { track_request(request_id) }
|
|
46
46
|
|
|
47
47
|
sleep(TRACK_SLEEP)
|
|
48
48
|
end
|
|
49
49
|
end
|
|
50
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
51
|
# Perform a track request
|
|
65
52
|
#
|
|
66
53
|
# @param request_id [String]
|
|
@@ -76,29 +63,10 @@ module Diffend
|
|
|
76
63
|
def build_request_object(request_id)
|
|
77
64
|
Diffend::RequestObject.new(
|
|
78
65
|
config: @config,
|
|
79
|
-
url:
|
|
66
|
+
url: @config.track_url(request_id),
|
|
80
67
|
payload: { id: request_id }.freeze,
|
|
81
68
|
request_method: :put
|
|
82
69
|
).freeze
|
|
83
70
|
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
71
|
end
|
|
104
72
|
end
|