diffend-monitor 0.2.28 → 0.2.34
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/.ruby-version +1 -1
- data/CHANGELOG.md +37 -1
- data/Gemfile +0 -2
- data/Gemfile.lock +4 -16
- data/certs/mensfeld.pem +21 -21
- data/config/diffend.yml +6 -0
- 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 +80 -0
- data/lib/diffend/configs/fetcher.rb +64 -0
- data/lib/diffend/configs/validator.rb +85 -0
- data/lib/diffend/errors.rb +2 -4
- 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 +27 -14
- data/lib/diffend/plugin.rb +86 -0
- data/lib/diffend/request.rb +12 -11
- data/lib/diffend/request_verdict.rb +52 -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 +46 -38
- metadata.gz.sig +0 -0
- data/lib/diffend/config/fetcher.rb +0 -121
- data/lib/diffend/config/file_finder.rb +0 -38
- 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 -222
metadata.gz.sig
CHANGED
Binary file
|
@@ -1,121 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'yaml'
|
4
|
-
|
5
|
-
module Diffend
|
6
|
-
# Module for all the components related to setting up the config
|
7
|
-
module Config
|
8
|
-
# Class responsible for fetching the config from .diffend.yml
|
9
|
-
module Fetcher
|
10
|
-
# All the errors for missing keys in the configuration file
|
11
|
-
MISSING_KEY_ERRORS = [
|
12
|
-
Errors::ProjectIdMissingInConfigurationFile,
|
13
|
-
Errors::ShareableIdMissingInConfigurationFile,
|
14
|
-
Errors::ShareableKeyMissingInConfigurationFile,
|
15
|
-
Errors::BuildPathMissingInConfigurationFile
|
16
|
-
].freeze
|
17
|
-
|
18
|
-
class << self
|
19
|
-
# @param build_path [String] path of the current build
|
20
|
-
#
|
21
|
-
# @return [OpenStruct] open struct with config details
|
22
|
-
#
|
23
|
-
# @example
|
24
|
-
# details = Fetcher.new.call('./')
|
25
|
-
# details.build_path #=> './'
|
26
|
-
def call(build_path)
|
27
|
-
build(build_path)
|
28
|
-
rescue Errors::MissingConfigurationFile
|
29
|
-
Bundler.ui.error(build_missing_error_message(build_path))
|
30
|
-
|
31
|
-
raise Diffend::Errors::HandledException
|
32
|
-
rescue Errors::EmptyConfigurationFile
|
33
|
-
Bundler.ui.error(build_empty_error_message(build_path))
|
34
|
-
|
35
|
-
raise Diffend::Errors::HandledException
|
36
|
-
rescue Errors::MalformedConfigurationFile
|
37
|
-
Bundler.ui.error(build_malformed_error_message(build_path))
|
38
|
-
|
39
|
-
raise Diffend::Errors::HandledException
|
40
|
-
rescue *MISSING_KEY_ERRORS => e
|
41
|
-
Bundler.ui.error(build_missing_key_error_message(e))
|
42
|
-
|
43
|
-
raise Diffend::Errors::HandledException
|
44
|
-
end
|
45
|
-
|
46
|
-
private
|
47
|
-
|
48
|
-
# @param build_path [String] path of the current build
|
49
|
-
#
|
50
|
-
# @return [OpenStruct] open struct with config details
|
51
|
-
def build(build_path)
|
52
|
-
content = ERB.new(
|
53
|
-
File.read(
|
54
|
-
FileFinder.call(build_path)
|
55
|
-
)
|
56
|
-
).result
|
57
|
-
|
58
|
-
raise Errors::EmptyConfigurationFile if content.empty?
|
59
|
-
|
60
|
-
OpenStruct.new(
|
61
|
-
parse_file(content)
|
62
|
-
.merge(build_path: build_path)
|
63
|
-
.merge(diffend_env: ENV['DIFFEND_ENV'] || 'development')
|
64
|
-
)
|
65
|
-
.tap(&Validator.method(:call))
|
66
|
-
end
|
67
|
-
|
68
|
-
def parse_file(content)
|
69
|
-
YAML.safe_load(content)
|
70
|
-
rescue Psych::SyntaxError
|
71
|
-
raise Errors::MalformedConfigurationFile
|
72
|
-
end
|
73
|
-
|
74
|
-
# @param build_path [String] path of the current build
|
75
|
-
#
|
76
|
-
# @return [String] missing configuration file message
|
77
|
-
def build_missing_error_message(build_path)
|
78
|
-
<<~MSG
|
79
|
-
\nWe were unable to locate Diffend configuration file.\n
|
80
|
-
Please make sure that .diffend.yml is present in #{build_path} folder.\n
|
81
|
-
MSG
|
82
|
-
end
|
83
|
-
|
84
|
-
# @return [String] empty configuration file message
|
85
|
-
def build_empty_error_message
|
86
|
-
<<~MSG
|
87
|
-
\nYour Diffend configuration file is empty.\n
|
88
|
-
Please re-setup.\n
|
89
|
-
MSG
|
90
|
-
end
|
91
|
-
|
92
|
-
# @return [String] malformed configuration file message
|
93
|
-
def build_malformed_error_message
|
94
|
-
<<~MSG
|
95
|
-
\nYour Diffend configuration file is malformed.\n
|
96
|
-
Please re-setup.\n
|
97
|
-
MSG
|
98
|
-
end
|
99
|
-
|
100
|
-
# @return [String] malformed configuration file message
|
101
|
-
def build_missing_key_error_message(exception)
|
102
|
-
missing_key = missing_key_from_exception(exception)
|
103
|
-
|
104
|
-
<<~MSG
|
105
|
-
\nYour Diffend configuration file is missing #{missing_key} key.\n
|
106
|
-
Please re-setup.\n
|
107
|
-
MSG
|
108
|
-
end
|
109
|
-
|
110
|
-
def missing_key_from_exception(exception)
|
111
|
-
case exception
|
112
|
-
when Errors::ProjectIdMissingInConfigurationFile then 'project_id'
|
113
|
-
when Errors::ShareableIdMissingInConfigurationFile then 'shareable_id'
|
114
|
-
when Errors::ShareableKeyMissingInConfigurationFile then 'shareable_key'
|
115
|
-
when Errors::BuildPathMissingInConfigurationFile then 'build_path'
|
116
|
-
end
|
117
|
-
end
|
118
|
-
end
|
119
|
-
end
|
120
|
-
end
|
121
|
-
end
|
@@ -1,38 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Diffend
|
4
|
-
module Config
|
5
|
-
# Class used to figure out the file from which we should load the settings
|
6
|
-
module FileFinder
|
7
|
-
# Names of the files or paths where we will look for the settings
|
8
|
-
#
|
9
|
-
# @note We do the double dot trick, to look outside of the current dir because when
|
10
|
-
# executed from a docker container, we copy the local uncommitted settings into the
|
11
|
-
# dir above the app location not to pollute the reset state of the git repo
|
12
|
-
#
|
13
|
-
# @note Order is important, as for local env we should load from
|
14
|
-
# local file (if present first)
|
15
|
-
FILE_NAMES = %w[
|
16
|
-
.diffend.yml
|
17
|
-
].map { |name| ["../#{name}", name] }.tap(&:flatten!).freeze
|
18
|
-
|
19
|
-
private_constant :FILE_NAMES
|
20
|
-
|
21
|
-
class << self
|
22
|
-
# Looks for Diffend settings file for a given env
|
23
|
-
#
|
24
|
-
# @param build_path [String] path of the current build
|
25
|
-
#
|
26
|
-
# @return [String] path to the file from which we should load all the settings
|
27
|
-
def call(build_path)
|
28
|
-
FILE_NAMES
|
29
|
-
.map { |name| File.join(build_path, name) }
|
30
|
-
.map { |name| Dir[name] }
|
31
|
-
.find { |selection| !selection.empty? }
|
32
|
-
.tap { |path| path || raise(Errors::MissingConfigurationFile) }
|
33
|
-
.first
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
@@ -1,25 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Diffend
|
4
|
-
# Module for all the components related to setting up the config
|
5
|
-
module Config
|
6
|
-
# Class responsible for validating the config from .diffend.yml
|
7
|
-
module Validator
|
8
|
-
class << self
|
9
|
-
# @param config [OpenStruct] path of the current build
|
10
|
-
def call(config)
|
11
|
-
raise Errors::ProjectIdMissingInConfigurationFile if missing?(config, 'project_id')
|
12
|
-
raise Errors::ShareableIdMissingInConfigurationFile if missing?(config, 'shareable_id')
|
13
|
-
raise Errors::ShareableKeyMissingInConfigurationFile if missing?(config, 'shareable_key')
|
14
|
-
raise Errors::BuildPathMissingInConfigurationFile if missing?(config, 'build_path')
|
15
|
-
end
|
16
|
-
|
17
|
-
private
|
18
|
-
|
19
|
-
def missing?(config, key)
|
20
|
-
config.public_send(key).nil? || config.public_send(key).empty?
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
@@ -1,304 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Diffend
|
4
|
-
module Voting
|
5
|
-
# Module responsible for handling both local and remote gem versions
|
6
|
-
module Versions
|
7
|
-
# Module responsible for preparing current or current/new versions of gems
|
8
|
-
class Local
|
9
|
-
# Definition of a local path, if it matches it means that we are the source
|
10
|
-
ME_PATH = '.'
|
11
|
-
# Sources that we expect to match ourselves too
|
12
|
-
ME_SOURCES = [
|
13
|
-
Bundler::Source::Gemspec,
|
14
|
-
Bundler::Source::Path
|
15
|
-
].freeze
|
16
|
-
# List of dependency types
|
17
|
-
DEPENDENCIES_TYPES = {
|
18
|
-
direct: 0,
|
19
|
-
dependency: 1
|
20
|
-
}.freeze
|
21
|
-
# List of sources types
|
22
|
-
SOURCES_TYPES = {
|
23
|
-
valid: 0,
|
24
|
-
multiple_primary: 1
|
25
|
-
}.freeze
|
26
|
-
# List of gem sources types
|
27
|
-
GEM_SOURCES_TYPES = {
|
28
|
-
local: 0,
|
29
|
-
gemfile_source: 1,
|
30
|
-
gemfile_git: 2,
|
31
|
-
gemfile_path: 3
|
32
|
-
}.freeze
|
33
|
-
|
34
|
-
class << self
|
35
|
-
# @param command [String] either install or update
|
36
|
-
# @param definition [Bundler::Definition] definition for your source
|
37
|
-
def call(command, definition)
|
38
|
-
Bundler.ui.silence { definition.resolve_remotely! }
|
39
|
-
|
40
|
-
instance = new(definition)
|
41
|
-
|
42
|
-
case command
|
43
|
-
when Commands::INSTALL, Commands::EXEC then instance.build_install
|
44
|
-
when Commands::UPDATE then instance.build_update
|
45
|
-
else
|
46
|
-
raise ArgumentError, "invalid command: #{command}"
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
# @param definition [Bundler::Definition] definition for your source
|
52
|
-
#
|
53
|
-
# @return [Hash] local dependencies
|
54
|
-
def initialize(definition)
|
55
|
-
@definition = definition
|
56
|
-
@direct_dependencies = Hash[definition.dependencies.map { |val| [val.name, val] }]
|
57
|
-
# Support case without Gemfile.lock
|
58
|
-
@locked_specs = @definition.locked_gems ? @definition.locked_gems.specs : []
|
59
|
-
end
|
60
|
-
|
61
|
-
# Build install specification
|
62
|
-
#
|
63
|
-
# @return [Hash]
|
64
|
-
def build_install
|
65
|
-
hash = build_main
|
66
|
-
|
67
|
-
@definition.specs.each do |spec|
|
68
|
-
next if skip?(spec.source)
|
69
|
-
|
70
|
-
locked_spec = @locked_specs.find { |s| s.name == spec.name }
|
71
|
-
|
72
|
-
hash['dependencies'][spec.name] = {
|
73
|
-
'platform' => build_spec_platform(spec, locked_spec),
|
74
|
-
'source' => build_spec_source(spec),
|
75
|
-
'type' => build_dependency_type(spec.name),
|
76
|
-
'versions' => build_versions(spec, locked_spec)
|
77
|
-
}
|
78
|
-
end
|
79
|
-
|
80
|
-
hash
|
81
|
-
end
|
82
|
-
|
83
|
-
# Build update specification
|
84
|
-
#
|
85
|
-
# @return [Hash]
|
86
|
-
def build_update
|
87
|
-
hash = build_main
|
88
|
-
|
89
|
-
@definition.specs.each do |spec|
|
90
|
-
next if skip?(spec.source)
|
91
|
-
|
92
|
-
locked_spec = @locked_specs.find { |s| s.name == spec.name }
|
93
|
-
|
94
|
-
hash['dependencies'][spec.name] = {
|
95
|
-
'platform' => build_spec_platform(spec, locked_spec),
|
96
|
-
'source' => build_spec_source(spec),
|
97
|
-
'type' => build_dependency_type(spec.name),
|
98
|
-
'versions' => build_versions(spec, locked_spec)
|
99
|
-
}
|
100
|
-
end
|
101
|
-
|
102
|
-
hash
|
103
|
-
end
|
104
|
-
|
105
|
-
private
|
106
|
-
|
107
|
-
# Build default specification
|
108
|
-
#
|
109
|
-
# @return [Hash]
|
110
|
-
def build_main
|
111
|
-
{
|
112
|
-
'dependencies' => {},
|
113
|
-
'sources' => build_sources,
|
114
|
-
'plugins' => {},
|
115
|
-
'platforms' => @definition.platforms.map(&:to_s)
|
116
|
-
}
|
117
|
-
end
|
118
|
-
|
119
|
-
# Build gem versions
|
120
|
-
#
|
121
|
-
# @param spec [Bundler::StubSpecification, Bundler::LazySpecification, Gem::Specification]
|
122
|
-
# @param locked_spec [Bundler::LazySpecification, Gem::Specification, NilClass]
|
123
|
-
#
|
124
|
-
# @return [Array<String>]
|
125
|
-
def build_versions(spec, locked_spec = nil)
|
126
|
-
if locked_spec && locked_spec.version.to_s != spec.version.to_s
|
127
|
-
[locked_spec.version.to_s, spec.version.to_s]
|
128
|
-
else
|
129
|
-
[spec.version.to_s]
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
|
-
# @param specs [Array] specs that are direct dependencies
|
134
|
-
# @param name [String] spec name
|
135
|
-
#
|
136
|
-
# @return [Boolean] dependency type
|
137
|
-
def build_dependency_type(name)
|
138
|
-
if @direct_dependencies.key?(name)
|
139
|
-
DEPENDENCIES_TYPES[:direct]
|
140
|
-
else
|
141
|
-
DEPENDENCIES_TYPES[:dependency]
|
142
|
-
end
|
143
|
-
end
|
144
|
-
|
145
|
-
# Build gem platform
|
146
|
-
#
|
147
|
-
# @param spec [Bundler::StubSpecification, Bundler::LazySpecification, Gem::Specification]
|
148
|
-
# @param locked_spec [Bundler::LazySpecification, Gem::Specification, NilClass]
|
149
|
-
#
|
150
|
-
# @return [String]
|
151
|
-
def build_spec_platform(spec, locked_spec)
|
152
|
-
parse_platform(
|
153
|
-
spec.platform || locked_spec&.platform || spec.send(:generic_local_platform)
|
154
|
-
)
|
155
|
-
end
|
156
|
-
|
157
|
-
# Parse gem platform
|
158
|
-
#
|
159
|
-
# @param platform [String, Gem::Platform]
|
160
|
-
#
|
161
|
-
# @return [String]
|
162
|
-
def parse_platform(platform)
|
163
|
-
case platform
|
164
|
-
when String then platform
|
165
|
-
when Gem::Platform then platform.os
|
166
|
-
end
|
167
|
-
end
|
168
|
-
|
169
|
-
# Build gem source type
|
170
|
-
#
|
171
|
-
# @param source [Bundler::Source] gem source type
|
172
|
-
#
|
173
|
-
# @return [Integer] internal gem source type
|
174
|
-
def build_spec_gem_source_type(source)
|
175
|
-
case source
|
176
|
-
when Bundler::Source::Metadata
|
177
|
-
GEM_SOURCES_TYPES[:local]
|
178
|
-
when Bundler::Source::Rubygems, Bundler::Source::Rubygems::Remote
|
179
|
-
GEM_SOURCES_TYPES[:gemfile_source]
|
180
|
-
when Bundler::Source::Git
|
181
|
-
GEM_SOURCES_TYPES[:gemfile_git]
|
182
|
-
when Bundler::Source::Path
|
183
|
-
GEM_SOURCES_TYPES[:gemfile_path]
|
184
|
-
else
|
185
|
-
raise ArgumentError, "unknown source #{source.class}"
|
186
|
-
end
|
187
|
-
end
|
188
|
-
|
189
|
-
# Build gem source
|
190
|
-
#
|
191
|
-
# @param spec [Bundler::StubSpecification, Bundler::LazySpecification, Gem::Specification]
|
192
|
-
#
|
193
|
-
# @return [Hash]
|
194
|
-
def build_spec_source(spec)
|
195
|
-
source = source_for_spec(spec)
|
196
|
-
|
197
|
-
{
|
198
|
-
'type' => build_spec_gem_source_type(source),
|
199
|
-
'value' => source_name_from_source(source)
|
200
|
-
}
|
201
|
-
end
|
202
|
-
|
203
|
-
# Figure out source for gem
|
204
|
-
#
|
205
|
-
# @param spec [Bundler::StubSpecification, Bundler::LazySpecification, Gem::Specification]
|
206
|
-
#
|
207
|
-
# @return [Bundler::Source] gem source type
|
208
|
-
def source_for_spec(spec)
|
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
|
220
|
-
spec.source
|
221
|
-
else
|
222
|
-
raise ArgumentError, "unknown source #{spec.source.class}"
|
223
|
-
end
|
224
|
-
end
|
225
|
-
|
226
|
-
# Build gem source name
|
227
|
-
#
|
228
|
-
# @param source [Bundler::Source] gem source type
|
229
|
-
#
|
230
|
-
# @return [String]
|
231
|
-
def source_name_from_source(source)
|
232
|
-
case source
|
233
|
-
when Bundler::Source::Metadata
|
234
|
-
''
|
235
|
-
when Bundler::Source::Rubygems::Remote
|
236
|
-
source_name(source.anonymized_uri)
|
237
|
-
when Bundler::Source::Git
|
238
|
-
source.instance_variable_get(:@safe_uri)
|
239
|
-
when Bundler::Source::Path
|
240
|
-
source.path
|
241
|
-
else
|
242
|
-
raise ArgumentError, "unknown source #{source.class}"
|
243
|
-
end
|
244
|
-
end
|
245
|
-
|
246
|
-
# @param uri [Bundler::URI]
|
247
|
-
#
|
248
|
-
# @return [String]
|
249
|
-
def source_name(uri)
|
250
|
-
uri.to_s[0...-1]
|
251
|
-
end
|
252
|
-
|
253
|
-
# Build sources used in the Gemfile
|
254
|
-
#
|
255
|
-
# @return [Array<Hash>]
|
256
|
-
def build_sources
|
257
|
-
sources = @definition.send(:sources).rubygems_sources
|
258
|
-
hash = {}
|
259
|
-
|
260
|
-
sources.each do |source|
|
261
|
-
type = build_source_type(source.remotes)
|
262
|
-
|
263
|
-
source.remotes.each do |src|
|
264
|
-
hash[source_name(src)] = type
|
265
|
-
end
|
266
|
-
end
|
267
|
-
|
268
|
-
hash.map { |name, type| { 'name' => name, 'type' => type } }
|
269
|
-
end
|
270
|
-
|
271
|
-
# Build gem source type
|
272
|
-
#
|
273
|
-
# @param remotes [Array<Bundler::URI>]
|
274
|
-
#
|
275
|
-
# @return [Integer] internal source type
|
276
|
-
def build_source_type(remotes)
|
277
|
-
remotes.count > 1 ? SOURCES_TYPES[:multiple_primary] : SOURCES_TYPES[:valid]
|
278
|
-
end
|
279
|
-
|
280
|
-
# Checks if we should skip a source
|
281
|
-
#
|
282
|
-
# @param source [Bundler::Source] gem source type
|
283
|
-
#
|
284
|
-
# @return [Boolean] true if we should skip this source, false otherwise
|
285
|
-
def skip?(source)
|
286
|
-
return true if me?(source)
|
287
|
-
|
288
|
-
false
|
289
|
-
end
|
290
|
-
|
291
|
-
# Checks if it's a self source, this happens for repositories that are a gem
|
292
|
-
#
|
293
|
-
# @param source [Bundler::Source] gem source type
|
294
|
-
#
|
295
|
-
# @return [Boolean] true if it's a self source, false otherwise
|
296
|
-
def me?(source)
|
297
|
-
return false unless ME_SOURCES.include?(source.class)
|
298
|
-
|
299
|
-
source.path.to_s == ME_PATH
|
300
|
-
end
|
301
|
-
end
|
302
|
-
end
|
303
|
-
end
|
304
|
-
end
|